AOP是面向切面编程,是相对于OOP面向对象编程而言的。Spring的AOP的存在的目的是为了解耦。AOP可让一组类共享相同的行为。在OOP中只能经过继承类和实现接口来实现,可是这样的缺点是会使代码的耦合度增长,且类继承只能为单继承,阻碍更多行为添加到一组类上,AOP的出现弥补了OOP的不足。java
使用@EnableAspectJAutoProxy注解开启Spring对AspectJ的支持。
添加@EnableAspectJAutoProxy注解,表示开启AOP代理自动配置,若是使用@EnableAspectJAutoProxy注解,表示使用cglib进行代理对象的生成。设置@EnableAspectJAutoProxy(exposeProxy=true)表示经过AOP框架暴露该代理对象,aopContext可以访问。spring
下面看一下@EnableAspectJAutoProxy这个类的源码编程
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Import(AspectJAutoProxyRegistrar.class) public @interface EnableAspectJAutoProxy { /** * Indicate whether subclass-based (CGLIB) proxies are to be created as opposed * to standard Java interface-based proxies. The default is {@code false}. */ // true--使用CGLIB基于类建立代理,false--使用java接口建立代理 boolean proxyTargetClass() default false; /** * Indicate that the proxy should be exposed by the AOP framework as a {@code ThreadLocal} * for retrieval via the {@link org.springframework.aop.framework.AopContext} class. * Off by default, i.e. no guarantees that {@code AopContext} access will work. * @since 4.3.1 */ // 是否经过aop矿建暴露该代理对象,aopContext可以访问 boolean exposeProxy() default false; }
经过上面的代码能够看出@EnableAspectJAutoProxy把AspectJAutoProxyRegistrar.class对象导入到了容器中。利用AspectJAutoProxyRegistrar给容器中注册了一个AnnotationAwareAspectJAutoProxyCreator。框架
AspectJAutoProxyRegistrar类中的registerBeanDefinitions方法主要实现了两个功能:ide
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar { /** * Register, escalate, and configure the AspectJ auto proxy creator based on the value * of the @{@link EnableAspectJAutoProxy#proxyTargetClass()} attribute on the importing * {@code @Configuration} class. */ @Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { //注册AnnotationAwareAspectJAutoProxyCreator AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry); //获取@EnableAspectJAutoProxy注解的属性信息 AnnotationAttributes enableAspectJAutoProxy = AnnotationConfigUtils.attributesFor(importingClassMetadata,EnableAspectJAutoProxy.class); if (enableAspectJAutoProxy != null) { if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) { AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry); } if (enableAspectJAutoProxy.getBoolean("exposeProxy")) { AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry); } } } }
@Nullable public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) { return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null); } //注册AnnotationAwareAspectJAutoProxyCreator @Nullable public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary( BeanDefinitionRegistry registry, @Nullable Object source) { return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source); } @Nullable private static BeanDefinition registerOrEscalateApcAsRequired( Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) { Assert.notNull(registry, "BeanDefinitionRegistry must not be null"); //判断是否包含目标bean if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) { BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME); if (!cls.getName().equals(apcDefinition.getBeanClassName())) { int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName()); int requiredPriority = findPriorityForClass(cls); if (currentPriority < requiredPriority) { apcDefinition.setBeanClassName(cls.getName()); } } return null; } RootBeanDefinition beanDefinition = new RootBeanDefinition(cls); beanDefinition.setSource(source); beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE); beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); //将beanDefinition注册到registry中,name为AUTO_PROXY_CREATOR_BEAN_NAME //AUTO_PROXY_CREATOR_BEAN_NAME = org.springframework.aop.config.internalAutoProxyCreator registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition); return beanDefinition; }