1、spring aop和aspectJ什么关系?
- aop是编程思想,spring aop被aspectJ都是aop思想的具体实现。
- spring aop为了不重复造轮子,通过一定的取舍选取了aspectJ中适合自己的注解。spring初期版本的aop只支持通过实现aop接口的方式来实现切面增强,后续版本增加支持XML配置方式,最新版本支持aspect的相关注解来定义切面。
2、spring aop的aspect注解引入
- spring通过@EnableAspectJAutoProxy注解,采用@import+ImportBeanDefinitionRegistrar方式将AnnotationAwareAspectJAutoProxyCreator.class类注册到容器。
- AnnotationAwareAspectJAutoProxyCreator实现了SmartInstantiationAwareBeanPostProcessor接口,通过重新BeanPostProcessor的postProcessBeforeInstantiation方法来做aop增强处理。
注:想要向spring容器注入自己的类对象除了这种方式外,还可以通过bean定义后置增强处理器BeanDefinitionRegistryPostProcessor进行注册。
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.*/@Overridepublic void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);AnnotationAttributes enableAspectJAutoProxy =AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);if (enableAspectJAutoProxy != null) {if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);}if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);}}}}
AbstractAutoProxyCreator#postProcessBeforeInstantiation源码:
@SuppressWarnings("serial")
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupportimplements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
@Overridepublic Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {Object cacheKey = getCacheKey(beanClass, beanName);if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {if (this.advisedBeans.containsKey(cacheKey)) {return null;}if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {this.advisedBeans.put(cacheKey, Boolean.FALSE);return null;}}// Create proxy here if we have a custom TargetSource.// Suppresses unnecessary default instantiation of the target bean:// The TargetSource will handle target instances in a custom fashion.TargetSource targetSource = getCustomTargetSource(beanClass, beanName);if (targetSource != null) {if (StringUtils.hasLength(beanName)) {this.targetSourcedBeans.add(beanName);}Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);this.proxyTypes.put(cacheKey, proxy.getClass());return proxy;}return null;}
}