一、概述
Spring中的AOP其实是通过动态代理来实现的,在bean的后置处理时,通过AnnotationAwareAspectJAutoProxyCreator这个后置处理器来生成代理类
二、@EnableAspectJAutoProxy
我们知道开启AOP是通过EnableAspectJAutoProxy注解,不然所有的切面都不会生效,下面我们来看下这个注解做了哪些事
@Configuration
@EnableAspectJAutoProxy
@ComponentScan
public class MyConfig {
...
}
@Aspect
@Component
public class LogAspects {
...
}
点击注解EnableAspectJAutoProxy进去看
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
...
}
可以看到这边有Import注解,我们知道Import注解可以导入一个ImportBeanDefinitionRegistrar接口的实现类,实现类的registerBeanDefinitions方法会在容器刷新过程中的invokeBeanFactoryPostProcessors被调用,
具体一会看,我们先看看AspectJAutoProxyRegistrar这个类,混个眼熟
//AspectJAutoProxyRegistrar
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public 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);
}
}
}
}
三、AnnotationAwareAspectJAutoProxyCreator
首先我们回顾下Spring核心方法refresh中的两个方法invokeBeanFactoryPostProcessors和registerBeanPostProcessors
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
//省略...
try {
//省略...
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
//省略...
}
catch (BeansException ex) {
//省略...
}
finally {
//省略...
}
}
}
我们在AspectJAutoProxyRegistrar类的registerBeanDefinitions方法上打个断点,启动一下服务,可以看到通过容器刷新方法中的invokeBeanFactoryPostProcessors这一步,最终会走到AspectJAutoProxyRegistrar类的这个
registerBeanDefinitions方法中,其实这边的知识是关于Import注解相关的,以后有机会再详细说
下面我们重点看下AspectJAutoProxyRegistrar类的registerBeanDefinitions方法
//AspectJAutoProxyRegistrar
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public 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);
}
}
}
}
点击registerAspectJAnnotationAutoProxyCreatorIfNecessary进去,一路往里进,最终到AopConfigUtils类的registerOrEscalateApcAsRequired方法
//AopConfigUtils
@Nullable
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(
BeanDefinitionRegistry registry, @Nullable Object source) {
return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}
//注意这个cls参数是AnnotationAwareAspectJAutoProxyCreator.class,记住这个类
@Nullable
private static BeanDefinition registerOrEscalateApcAsRequired(
Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
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;
}
//包装成BeanDefinition
RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
beanDefinition.setSource(source);
//把优先级调成最高
beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
//注册AnnotationAwareAspectJAutoProxyCreator这个BeanDefinition,
//名字叫org.springframework.aop.config.internalAutoProxyCreator
registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
return beanDefinition;
}
这个时候,AnnotationAwareAspectJAutoProxyCreator已经放到了beanDefinitionMap里,等待被实例化和初始化,那么AnnotationAwareAspectJAutoProxyCreator是在什么时候实例化和初始化的呢,我们先看下AnnotationAwareAspectJAutoProxyCreator的类图
可以看到AnnotationAwareAspectJAutoProxyCreator是BeanPostProcessor接口的实例,而BeanPostProcessor的实例化和初始化是registerBeanPostProcessors中完成的,我们找到这段代码,从上面我们知道AnnotationAwareAspectJAutoProxyCreator是加了Order属性的,所以走的是如下这段代码
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
//省略...
// Next, register the BeanPostProcessors that implement Ordered.
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
for (String ppName : orderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
sortPostProcessors(orderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
//省略...
}
可以看到9行getBean,点进去,进入到类AbstractBeanFactory的getBean方法
//AbstractBeanFactory
@Override
public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
return doGetBean(name, requiredType, null, false);
}
看过Spring中bean初始化代码的小伙伴都熟悉了,doGetBean中就是对bean做初始化,到此时AnnotationAwareAspectJAutoProxyCreator完成了初始化,放到了容器中,我们知道AnnotationAwareAspectJAutoProxyCreator是实现了BeanPostProcessor接口的实例,会在bean对象创建之后调用其postProcessAfterInitialization方法,这个方法在抽象父类AbstractAutoProxyCreator中
//AbstractAutoProxyCreator
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey)) {
//包装如果必要的话
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
继续点击7行wrapIfNecessary进去
//AbstractAutoProxyCreator
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// 看一看这个bean有没有通知方法或者增强器,如果有就创建代理对象
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
//把bean包装成代理对象proxy
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
点击18行createProxy进去
//AbstractAutoProxyCreator
protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
@Nullable Object[] specificInterceptors, TargetSource targetSource) {
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}
//先创建proxyFactory工厂类,用于创建代理对象
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
//将当前bean适合的advice,重新封装成Advisor类,然后添加到ProxyFactory中
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
//封装成代理类
return proxyFactory.getProxy(getProxyClassLoader());
}
点击34行getProxy进到ProxyFactory类的getProxy方法中
//ProxyFactory
public Object getProxy(@Nullable ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader);
}
继续点击getProxy来到接口AopProxy中
//AopProxy
Object getProxy(@Nullable ClassLoader classLoader);
我们看看getProxy的实现
可以看到分为两种创建代理类的方式,分别是jdk和cglib,选择jdk的方式看下
//JdkDynamicAopProxy
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
}
Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
//jdk动态代理的标准用法
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
可以看到jdk动态代理的标准用法
四、过程总结
1、在容器刷新过程中的invokeBeanFactoryPostProcessors方法里把AnnotationAwareAspectJAutoProxyCreator注册到beanDefinitionMap里;
2、在容器刷新过程中的registerBeanPostProcessors方法里完成了初始化;
3、AnnotationAwareAspectJAutoProxyCreator类的postProcessAfterInitialization方法(实际在其父类AbstractAutoProxyCreator中)讲所有有advice的bean对象重新包装成proxy对象;
4、调用bean方法是会通过其代理类proxy来依次调用增强器的相关方法;
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/154506.html