Spring注解驱动开发之AOP
AOP概念:
切入点(pointcut):需要增强的目标方法。
连接点(joinpoint):方法连接点,方法有关的前前后后都是连接点。即切点的全集。
通知(advice):某个方法在执行前或执行后要完成的工作
切面(aspect):切点和通知共同定义了切面的全部功能——它是什么,在何时何处完成其功能,切面就是横切关注点的抽象。
动态代理:Spring AOP使用动态代理,所谓动态代理即AOP框架不会修改原来的对象,而是在需要的时候重新生成一个代理对象,这个代理对象包含了目标对象的全部发放,并且在指定的切点做了处理,而且最终还是回调原对象的方法。
动态代理有两种方式,JDK动态代理和CGLIB动态代理。
JDK动态代理通过反射来接收被代理的类,并且要求被代理的类必须实现一个接口,其核心是InvocationHandler接口和Proxy类。
如果目标类没有实现接口,那就要选择使用CGLIB来动态代理目标类。CGLIB是通过继承的方式做的动态代理,因此,如果某个类被标记为final,那么它是无法使用CGLIB做动态代理。CGLIB会使生成的代理类继承当前的对象,并在代理类中对代理方法进行强化处理(前置处理、后置处理等)。

1、AOP基本搭建:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>4.3.8.RELEASE</version>
</dependency>
@Configuration
@ComponentScan(value = "com.aop.test")
@EnableAspectJAutoProxy
public class ConfigAOP {
}
@Aspect
@Component
public class LogAspects {
@Pointcut("execution( public int com.aop.test.MathCaculator.div(..))")
public void pointcut(){
}
@Before("pointcut()")
public void logstart(JoinPoint joinPoint){
System.out.println("@Before aop方法运行开始。。。。获取方法名:"+joinPoint.getSignature().getName()+
"获取方法的参数列表:" +Arrays.asList(joinPoint.getArgs()));
}
@After("pointcut()")
public void logEnd(){
System.out.println("@After: aop方法运算结束");
}
@AfterReturning("pointcut()")
public void logReturn(){
System.out.println("@AfterReturning: aop方法返回");
}
@AfterThrowing(value = "pointcut()",throwing = "exception")
public void logException(Exception exception){
System.out.println("@AfterThrowing 打印aop方法异常信息:");
}
}
@Component
public class MathCaculator {
public int div(int a,int b) throws Exception {
System.out.println("除法的方法主体");
return a/b;
}
}
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Main {
public static void main(String[] args) throws Exception {
AnnotationConfigApplicationContext annotationConfigApplicationContext=new AnnotationConfigApplicationContext(ConfigAOP.class);
System.out.println("容器初始化成功");
MathCaculator MathCaculator = annotationConfigApplicationContext.getBean(MathCaculator.class);
MathCaculator.div(1,0);
annotationConfigApplicationContext.close();
}
}
2、AOP的简单注解:
在配置类中:@EnableAspectJAutoProxy(开启基于注解的aop模式)
切面类:@Aspect(告诉Spring哪个是切面类,切面类也要要注解@Component才能将切面类加入到注解中)
3、AOP源码解析(aop原理即:给容器中注册了哪些组件,这些组件什么时候工作,以及组件功能是什么):
@EnableAspectJAutoProxy 开始源码分析:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
}
- 在这里可以看到导入了一个组件AspectJAutoProxyRegistrar.class,利用它,可以自定义注册bean。
org.springframework.aop.config.internalAutoProxyCreator -> org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator
给容器中注册一个类型为AnnotationAwareAspectJAutoProxyCreator名字为internalAutoProxyCreator的bean 。
- 给容器注入AnnotationAwareAspectJAutoProxyCreator的作用:
该类实现了接口SmartInstantiationAwareBeanPostProcessor和BeanFactoryAware,其中BeanPostProcessor接口关注在bean初始化前后做的事情,BeanFactoryAware接口关注自动装配BeanFactory

流程:
1)传入配置类,创建ioc容器。
AnnotationConfigApplicationContext annotationConfigApplicationContext=new AnnotationConfigApplicationContext(ConfigAOP.class);
2)注册配置类,调用refresh()刷新容器

3)registerBeanPostProcessors(beanFactory); 注册bean的后置处理器来方便拦截bean的创建


浙公网安备 33010602011771号