Spring中的AOP動態(tài)代理源碼詳解
一、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 注解部分。
@EnableAspectJAutoProxy 注解源碼,使用 @Import 注解,向 Spring 容器中導(dǎo)入 AspectJAutoProxyRegistrar 類,而 AspectJAutoProxyRegistrar 類實現(xiàn) ImportBeanDefinitionRegistrar 接口。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
boolean proxyTargetClass() default false;
boolean exposeProxy() default false;
}AOP 的原理和 Mybatis 的原理一樣,都是通過實現(xiàn) ImportBeanDefinitionRegistrar 接口, Mybatis 的實現(xiàn)類是 MapperScannerRegistrar ,而 AOP 的實現(xiàn)類是 AspectJAutoProxyRegistrar 。
// Mybatis
class MapperScannerRegistrar implements ImportBeanDefinitionRegistrar
// AOP
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar
2. 執(zhí)行Import導(dǎo)入類
在 parser.parse(candidates); 這行代碼里完成了對 @Import 注解的導(dǎo)入工作,并對實現(xiàn) ImportBeanDefinitionRegistrar 接口的類完成了實例化,并把已經(jīng)創(chuàng)建好的實列放到了 ConfigurationClass 類的屬性 importBeanDefinitionRegistrars 中,可以看下面斷點圖。

this.reader.loadBeanDefinitions() 這個方法中完成了對 ImportBeanDefinitionRegistrar 接口方法的調(diào)用。
下面就來看一下 AspectJAutoProxyRegistrar 類中實現(xiàn) ImportBeanDefinitionRegistrar 接口的方法了。
AOP 的入口就在這里!?。。?/p>
二、AOP源碼分析
1. AspectJAutoProxyRegistrar類
來看一下 AspectJAutoProxyRegistrar 類中實現(xiàn) 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 < requiredPriority) {
apcDefinition.setBeanClassName(cls.getName());
}
}
return null;
}
// 此處的的beanClass為AnnotationAwareAspectJAutoProxyCreator.class
RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
beanDefinition.setSource(source);
beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
// 往beanDefinitionMap中注冊一個beanName為org.springframework.aop.config.internalAutoProxyCreator的BeanDefinition
registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
return beanDefinition;
}

2. internalAutoProxyCreator類
再觀察一下 internalAutoProxyCreator ,它的實現(xiàn)類是 org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator

經(jīng)過 refresh() 方法中的 registerBeanPostProcessors() 方法, BeanPostProcessor 就已經(jīng)實例化了,并且添加到了 beanFactory 工廠中的 beanPostProcessors 屬性中。


3. BeanPostProcessor方法執(zhí)行
我們要來看一下 BeanPostProcessor 的執(zhí)行時機(jī),在 populateBean() 屬性賦值之后的 initializeBean() 方法中,進(jìn)行了 Bean后置處理器 方法的調(diào)用。
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
// 權(quán)限檢查
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
} else {
// 執(zhí)行setBeanName/setBeanFactory賦值
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// 調(diào)用BeanPostProcessor接口中的postProcessBeforeInitialization()方法
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// 執(zhí)行自定義的init-method方法
invokeInitMethods(beanName, wrappedBean, mbd);
} catch (Throwable ex) {
// 拋異常代碼略
}
if (mbd == null || !mbd.isSynthetic()) {
// 調(diào)用BeanPostProcessor接口中的postProcessAfterInitialization()方法
// AOP代理就在AnnotationAwareAspectJAutoProxyCreator類此方法中
// AnnotationAwareAspectJAutoProxyCreator的父類AbstractAutoProxyCreator實現(xiàn)了此方法
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}上面這個 AnnotationAwareAspectJAutoProxyCreator 類中的 postProcessAfterInitialization() 方法執(zhí)行過后, 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);
// 創(chuàng)建代理對象
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 {
// 這個判斷很重要,可以通過配置文件進(jìn)行配置,來決定采用什么動態(tài)代理
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
Class<?> targetClass = config.getTargetClass();
if (targetClass == null) {
// 拋異常略
}
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
// 創(chuàng)建JDK動態(tài)代理
return new JdkDynamicAopProxy(config);
}
// 創(chuàng)建Cglib動態(tài)代理
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}三、小結(jié)
AOP的原理和Mybatis的原理一樣,都是利用了Spring中@Import導(dǎo)入ImportBeanDefinitionRegistrar這個擴(kuò)展點。
先往容器中添加一個BeanDefinition,然后再適當(dāng)?shù)臅r機(jī)進(jìn)行方法的調(diào)用。
到此這篇關(guān)于Spring中的AOP動態(tài)代理源碼詳解的文章就介紹到這了,更多相關(guān)AOP動態(tài)代理源碼內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用IDEA對SpringBoot應(yīng)用進(jìn)行遠(yuǎn)程調(diào)試方式
文章介紹了如何在IDEA中對部署在服務(wù)器上的SpringBoot應(yīng)用進(jìn)行遠(yuǎn)程調(diào)試,通過配置遠(yuǎn)程調(diào)試端口和啟動參數(shù),本地IDEA可以設(shè)置斷點并進(jìn)行調(diào)試2025-02-02
SwiftUI中級List如何添加新內(nèi)容(2020年教程)
這篇文章主要介紹了SwiftUI中級List如何添加新內(nèi)容,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-01-01
spring+hibernate 兩種整合方式配置文件的方法
本篇文章主要介紹了spring+hibernate 兩種整合方式配置文件的方法,主要有兩種方式 1、注解方式 2、xml方式實現(xiàn),有興趣的可以了解一下。2017-04-04
SpringBoot核心@SpringBootApplication使用介紹
這篇文章主要介紹了SpringBoot核心@SpringBootApplication的使用,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-03-03
Java實現(xiàn)自定義中文排序的方法機(jī)注意事項
在Java中,中文排序通常涉及到使用Collator類來處理字符串的比較,確保根據(jù)漢字的拼音順序進(jìn)行排序,本文給大家介紹了Java實現(xiàn)自定義中文排序的方法機(jī)注意事項,并有相關(guān)的代碼示例供大家參考,需要的朋友可以參考下2024-10-10
SpringBoot 指標(biāo)監(jiān)控actuator的專題
未來每一個微服務(wù)在云上部署以后,我們都需要對其進(jìn)行監(jiān)控、追蹤、審計、控制等。SpringBoot就抽取了Actuator場景,使得我們每個微服務(wù)快速引用即可獲得生產(chǎn)級別的應(yīng)用監(jiān)控、審計等功能,通讀本篇對大家的學(xué)習(xí)或工作具有一定的價值,需要的朋友可以參考下2021-11-11

