Aop:aspect oriented programming 面向切面编程
Oop:object oriented programming 面向对象编程
Aop在spring 中作用:
提供声明式服务。(声明式事务)
允许用户实现自定义切面。
传统的编程:
jsp-》action-》service-》dao
至上而下,纵向编程
Aop 的编程方式:在不改变原有代码的情况下,增加新的功能。横向的编程。
aop的好处:
使得真实角色处理的业务更加纯粹,不再去关注一些公共的事情。
公共的业务由代理来完成--实现的业务的分工。
公共业务发生扩展时变得更加集中和方便。
名词解释:
关注点:指的是增加的某个业务如日志log 安全检查,缓存的处理,事务,异常处理等。
切面(aspect):一个关注点的模块化。这个关注点可能会横切多个对象。
连接点(joinpoint):在程序执行过程中某个特定的点,比如某方法调用的时候或者处理异常的时候。在springAop中一个连接点表示的一个方法的执行。
通知(advice):在切面的某个特定的连接点上执行的动作。其中包括了around before after等不同类型的通知。
前置通知(before advice)在某连接点之前执行的通知。
后置通知(after returning advice ):在某连接点正常完成后执行的通知:例如一个方法没有抛出任何异常,正常返回。
异常通知(after throwing advice):在方法抛出异常退出时执行的通知。
最终通知(around advice):包围一个连接点的通知,例如方法调用。
目标对象:被代理的对象就是目标对象。
Aop代理(Aop Proxy):Aop 框架创建的对象,用来实现切面契约。在spring中,Aop代理可以是jdk动态代理或者
,CGLIB代理。
织入:(weaving)把切面连接到其他的应用程序类型或者对象上,并创建一个被通知对象。
spring 实现Aop:3种方式
第一种:通过通知来实现Aop 也就是提供了接口 实现就行
MethodBeforeAdvice
AfterReturningAdvice
ThrowsAdvice
通过spring的API 来实现Aop 需要导入的包
public void before(Method method, Object[] args, Object target) throws Throwable { //method指的是 切入点的方法对象(被调用的方法对象) //args被调用的方法的参数 //target 被调用的方法的目标对象 System.out.println(target.getClass().getName()+"---"+method.getName()); }
beans.xml 有所改变
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> </beans>
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <bean id="userService" class="service.UserServiceImpl"></bean> <bean id="log" class="log.Log"></bean> <aop:config> <aop:pointcut expression="execution(* service.UserServiceImpl.*(..))" id="pointcut"/>//expression表示.* 类的所有方法 ,(..)以及所有参数。 <aop:advisor advice-ref="log" pointcut-ref="pointcut"/>//前置 <aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>//后置 </aop:config> </beans>
//前置通知
//目标类package log; import java.lang.reflect.Method; import org.springframework.aop.MethodBeforeAdvice; public class Log implements MethodBeforeAdvice{ public void log(){} @Override public void before(Method method, Object[] args, Object target) throws Throwable { System.out.println(target.getClass().getName()+"---"+method.getName()); } }
package service; public class UserServiceImpl implements UserService { @Override public void add() { System.out.println("addUser"); } @Override public void update() { System.out.println("updateUser"); } @Override public void search() { System.out.println("searchUser"); } @Override public void delete() { System.out.println("deleteUser"); } }
package service; public interface UserService { public void add(); public void update(); public void search(); public void delete(); }
//后置通知package test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import service.UserService; public class Test { public static void main(String[] args){ ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); UserService user = (UserService)context.getBean("userService"); user.add(); } }
package log; import java.lang.reflect.Method; import org.springframework.aop.AfterReturningAdvice; public class AfterLog implements AfterReturningAdvice{ /** * 目标方法执行后执行的通知 * @param * returnValue 返回值 * method被调用的方法 * args被调用方法对象的参数 * target 被调用的对象 */ @Override public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable { System.out.println(target.getClass().getName()+">>"+method.getName()+">>"+returnValue); } }
Aop的一个重要性:
spring就是将公共的业务类(如:日志,安全,权限,缓存等)和领域业务类结合,当执行领域业务时,将会把公共业务加进来。实现公共业务的重复利用。好处是领域业务更纯粹,程序员专注于领域业务。其本质还是动态代理。
第二种方式实现Aop:
自定义类来实现Aop
业务类也是用的UserService和UserServiceImplpackage log; public class Log { public void before(){ System.out.println("方法执行前"); } public void after(){ System.out.println("方法执行后"); } }
配置文件:beans.xml;
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <bean id="userService" class="impl.UserServiceImpl"></bean> <bean id="log" class="log.Log"></bean> <aop:config> <aop:pointcut expression="execution(* impl.*.(..))" id="pointcut"/> <aop:aspect ref="log"> <aop:pointcut expression="execution(* impl.*.*(..))" id="pointcut"/> <aop:before method="before" pointcut-ref="pointcut"/> <aop:after method="after" pointcut-ref="pointcut"/> </aop:aspect> </aop:config> </beans>
Log.java第三种实现方法:通过注解实现Aop
业务类还是Userservice 和UserServiceImplpackage log; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; @Aspect public class Log { @Before("execution(* impl.*.*(..))") public void before(){ System.out.println("方法执行前"); } @After("execution(* impl.*.*(..))") public void after(){ System.out.println("方法执行后"); } @Around("execution(* impl.*.*(..))") // 环绕前 是在Before执行前,执行 //环绕后 是在@After执行前,执行 public Object around(ProceedingJoinPoint jp) throws Throwable{ System.out.println("环绕前"); System.out.println("签名"+jp.getSignature());//签名 //执行目标方法 Object result = jp.proceed(); System.out.println("环绕后"); return result; } }
配置文件:beans.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <bean id="userService" class="impl.UserServiceImpl"></bean> <bean id="log" class="log.Log"></bean> <aop:aspectj-autoproxy /> </beans>
领域业务---领域模型:
例如:
支付业务---接入第三方接口---安全检查---进行身份验证--资金验证---支付功能
log.() 分离的思想。