- 一、Spring启动流程再分析
- 1. 处理Import过程
- 2. 执行Import导入类
- 二、AOP源码分析
- 1. AspectJAutoProxyRegistrar类
- 2. internalAutoProxyCreator类
- 3. BeanPostProcessor方法执行
- 三、小结
Spring源码系列(八)——Mybatis是如何整合进Spring源码分析
https://blog.csdn.net/zxd1435513775/article/details/121180974
一、Spring启动流程再分析配置类,开启AOP
的注解@EnableAspectJAutoProxy
@Configuration
@ComponentScan("com.scorpios")
@EnableAspectJAutoProxy
public class AppConfig {
}
切面类
@Aspect
@Component
public class AspectJScorpios {
@Pointcut("execution(* com.scorpios.service..*.*(..))")
public void pointCut(){
}
@Before("pointCut()")
public void before(){
System.out.println(" proxy before ... ");
}
}
启动类
public static void main( String[] args )
{
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext();
ac.register(AppConfig.class);
ac.refresh();
XService xService = (XService) ac.getBean("XService");
xService.print();
}
1. 处理Import过程
对于Import
的处理过程,可以看一下源码分析第四篇,包扫描中处理@Import
注解部分。
Spring源码系列(四)——ConfigurationClassPostProcessor功能解析
https://blog.csdn.net/zxd1435513775/article/details/120935494
@EnableAspectJAutoProxy
注解源码,使用@Import
注解,向Spring
容器中导入AspectJAutoProxyRegistrar
类,而AspectJAutoProxyRegistrar
类实现ImportBeanDefinitionRegistrar
接口。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
boolean proxyTargetClass() default false;
boolean exposeProxy() default false;
}
关于@Import
注解导入ImportBeanDefinitionRegistrar
实现类的介绍可以看一下Spring源码系列(八),
AOP
的原理和Mybatis
的原理一样,都是通过实现ImportBeanDefinitionRegistrar
接口,Mybatis
的实现类是MapperScannerRegistrar
,而AOP
的实现类是AspectJAutoProxyRegistrar
。
// Mybatis
class MapperScannerRegistrar implements ImportBeanDefinitionRegistrar
// AOP
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar
2. 执行Import导入类在parser.parse(candidates);
这行代码里完成了对@Import
注解的导入工作,并对实现ImportBeanDefinitionRegistrar
接口的类完成了实例化,并把已经创建好的实列放到了ConfigurationClass
类的属性importBeanDefinitionRegistrars
中,可以看下面断点图。
this.reader.loadBeanDefinitions()
这个方法中完成了对ImportBeanDefinitionRegistrar
接口方法的调用。
下面就来看一下AspectJAutoProxyRegistrar
类中实现ImportBeanDefinitionRegistrar
接口的方法了。AOP
的入口就在这里!!!!
来看一下AspectJAutoProxyRegistrar
类中实现ImportBeanDefinitionRegistrar
接口方法。
该方法的作用就是往Spring
容器中添加一个BeanDefinition
,beanName
为org.springframework.aop.config.internalAutoProxyCreator
。beanClass
为AnnotationAwareAspectJAutoProxyCreator.class
。
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);
}
}
}
}
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null);
}
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(
BeanDefinitionRegistry registry, @Nullable Object source) {
return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}
private static BeanDefinition registerOrEscalateApcAsRequired(
Class cls, BeanDefinitionRegistry registry, @Nullable Object source) {
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 {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
} else {
// 执行setBeanName/setBeanFactory赋值
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// 调用BeanPostProcessor接口中的postProcessBeforeInitialization()方法
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// 执行自定义的init-method方法
invokeInitMethods(beanName, wrappedBean, mbd);
} catch (Throwable ex) {
// 抛异常代码略
}
if (mbd == null || !mbd.isSynthetic()) {
// 调用BeanPostProcessor接口中的postProcessAfterInitialization()方法
// AOP代理就在AnnotationAwareAspectJAutoProxyCreator类此方法中
// AnnotationAwareAspectJAutoProxyCreator的父类AbstractAutoProxyCreator实现了此方法
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
上面这个AnnotationAwareAspectJAutoProxyCreator
类中的postProcessAfterInitialization()
方法执行过后,XService
实例就变成了Cglib
代理对象了。
下面来分析下源码:
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
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;
}
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
// 创建代理对象
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;
}
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 = new ProxyFactory();
proxyFactory.copyFrom(this);
if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
evaluateProxyInterfaces(beanClass, 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());
}
public Object getProxy(@Nullable ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader);
}
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
return getAopProxyFactory().createAopProxy(this);
}
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
// 这个判断很重要,可以通过配置文件进行配置,来决定采用什么动态代理
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
Class targetClass = config.getTargetClass();
if (targetClass == null) {
// 抛异常略
}
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
// 创建JDK动态代理
return new JdkDynamicAopProxy(config);
}
// 创建Cglib动态代理
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
三、小结
AOP
的原理和Mybatis
的原理一样,都是利用了Spring
中@Import
导入ImportBeanDefinitionRegistrar
这个扩展点。先往容器中添加一个BeanDefinition
,然后再适当的时机进行方法的调用。
两篇文章可以对比着看。