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; }