目錄
- 一、AOP基礎用例準備
- 二、時機點分析
- 三、代理物件創建流程
一、AOP基礎用例準備
Bean定義
@Component
public class LagouBean {
public void tech(){
System.out.println("java learning......");
}
}
Aspect定義
package com.lagou;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
@Component
@Aspect
public class LagouAspect {
@Pointcut("execution(* com.lagou.*.*(..))")
public void pointcut(){
}
@Before("pointcut()")
public void before() {
System.out.println("before method ......");
}
}
測驗用例
/**
* 測驗用例:Aop 代理物件創建
*/
@Test
public void testAopProxyBuild(){
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfig.class);
LagouBean lagouBean = applicationContext.getBean(LagouBean.class);
lagouBean.tech();
}
本文參考資料《Spring高級原始碼筆記》,需要的同學添加助理VX:
C18173184271,備注一下CSDN+作業年限!免費獲取
二、時機點分析

我們發現在 getBean 之前,LagouBean物件已經產生(即在第一行初始化代碼中完成),而且該物件是一個代理物件(Cglib代理物件),我們斷定,容器初始化程序中目標Ban已經完成了代理,回傳了代理物件,
三、代理物件創建流程
AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object,org.springframework.beans.factory.support.RootBeanDefinition)
/**
*
* 初始化Bean
包括Bean后置處理器初始化
Bean的一些初始化方法的執行init-method
Bean的實作的宣告周期相關介面的屬性注入
*/
protected Object initializeBean(final String beanName, final Object bean,
@Nullable RootBeanDefinition mbd) {
// 執行所有的AwareMethods
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// 執行所有的BeanPostProcessor#postProcessBeforeInitialization 初始化之前的處理器方法
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean,beanName);
}
try {
// 這里就開始執行afterPropertiesSet(實作了InitializingBean介面)方法和initMethod
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException((mbd != null ? mbd.getResourceDescription() : null),beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
// 整個Bean初始化完成,執行后置處理器方法
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean,beanName);
}
return wrappedBean;
}
AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
// 回圈執行后置處理器
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result,beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}

創建代理物件的后置處理器AbstractAutoProxyCreator#postProcessAfterInitialization
/**
* Create a proxy with the configured interceptors if the bean is
* identified as one to proxy by the subclass.
* @see #getAdvicesAndAdvisorsForBean
*/
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName){
if (bean != null) {
// 檢查下該類是否已經暴露過了(可能已經創建了,比如A依賴B時,創建A時候,就會先去創建B,
// 當真正需要創建B時,就沒必要再代理一次已經代理過的物件),避免重復創建
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
AbstractAutoProxyCreator#wrapIfNecessary
/**
* Wrap the given bean if necessary, i.e. if it is eligible for being
proxied.
* @param bean the raw bean instance
* @param beanName the name of the bean
* @param cacheKey the cache key for metadata access
* @return a proxy wrapping the bean, or the raw bean instance as-is
*/
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
// targetSourcedBeans包含,說明前面創建過
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;
}
// Create proxy if we have advice.
// 得到所有候選Advisor,對Advisors和bean的方法雙層遍歷匹配,最終得到一個
List<Advisor>,即specificInterceptors 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;
}
AbstractAutoProxyCreator#createProxy
/**
* Create an AOP proxy for the given bean.
* 為指定 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 proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
// 根據一些情況判斷是否要設定proxyTargetClass=true
if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
// 把指定和通用攔截物件合并, 并都適配成Advisor
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());
}
接著跟進到ProxyFactory中
public class ProxyFactory extends ProxyCreatorSupport {
public Object getProxy(ClassLoader classLoader) {
// 用ProxyFactory創建AopProxy, 然后用AopProxy創建Proxy, 所以這里重要的是看獲取的AopProxy
// 物件是什么,
// 然后進去看怎么創建動態代理, 提供了兩種:jdk proxy, cglib
return createAopProxy().getProxy(classLoader);
}
}
public class ProxyCreatorSupport extends AdvisedSupport {
private AopProxyFactory aopProxyFactory;
public ProxyCreatorSupport() {
this.aopProxyFactory = new DefaultAopProxyFactory();
}
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
//先獲取創建AopProxy的工廠, 再由此創建AopProxy
return getAopProxyFactory().createAopProxy(this);
}
public AopProxyFactory getAopProxyFactory() {
return this.aopProxyFactory;
}
}
流程就是用AopProxyFactory創建AopProxy, 再用AopProxy創建代理物件,這里的AopProxyFactory默認是DefaultAopProxyFactory,看他的createAopProxy方法
public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
Class<?> targetClass = config.getTargetClass();
if (targetClass == null) {
throw new AopConfigException("TargetSource cannot determine target class: " + "Either an interface or a target is required for proxy creation.");
}
if (targetClass.isInterface()) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
} else {
return new JdkDynamicAopProxy(config);
}
}
/**
* Determine whether the supplied {@link AdvisedSupport} has only the
* {@link org.springframework.aop.SpringProxy} interface specified (or no
* proxy interfaces specified at all).
*/
private boolean hasNoUserSuppliedProxyInterfaces(AdvisedSupport config) {
Class<?>[] interfaces = config.getProxiedInterfaces();
return (interfaces.length == 0 || (interfaces.length == 1 && SpringProxy.class.equals(interfaces[0])));
}
}
這里決定創建代理物件是用JDK Proxy,還是用 Cglib 了,最簡單的從使用方面使用來說:設定proxyTargetClass=true強制使用Cglib 代理,什么引數都不設并且物件類實作了介面則默認用JDK 代理,如果沒有實作介面則也必須用Cglib
ProxyFactory#getProxy(java.lang.ClassLoader)
------ CglibAopProxy#getProxy(java.lang.ClassLoader)
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating CGLIB proxy: " + this.advised.getTargetSource());
}
try {
Class<?> rootClass = this.advised.getTargetClass();
Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
Class<?> proxySuperClass = rootClass;
if (ClassUtils.isCglibProxyClass(rootClass)) {
proxySuperClass = rootClass.getSuperclass();
Class<?>[] additionalInterfaces = rootClass.getInterfaces();
for (Class<?> additionalInterface : additionalInterfaces) {
this.advised.addInterface(additionalInterface);
}
}
// Validate the class, writing log messages as necessary.
validateClassIfNecessary(proxySuperClass, classLoader);
// 配置 Cglib 增強
Enhancer enhancer = createEnhancer();
if (classLoader != null) {
enhancer.setClassLoader(classLoader);
if (classLoader instanceof SmartClassLoader && ((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
enhancer.setUseCache(false);
}
}
enhancer.setSuperclass(proxySuperClass);
enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
enhancer.setStrategy(new ClassLoaderAwareUndeclaredThrowableStrategy(classLoader));
Callback[] callbacks = getCallbacks(rootClass);
Class<?>[] types = new Class<?>[callbacks.length];
for (int x = 0; x < types.length; x++) {
types[x] = callbacks[x].getClass();
}
// fixedInterceptorMap only populated at this point, after getCallbacks call above
enhancer.setCallbackFilter(new ProxyCallbackFilter(
this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
enhancer.setCallbackTypes(types);
// 生成代理類,并且創建?個代理類的實體
return createProxyClassAndInstance(enhancer, callbacks);
}
catch (CodeGenerationException | IllegalArgumentException ex) {
throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() + ": Common causes of this problem include using a final class or anon-visible class",ex);
}
catch (Throwable ex) {
// TargetSource.getTarget() failed
throw new AopConfigException("Unexpected AOP exception", ex);
}
}
AOP原始碼分析類方法呼叫關系
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#i
nitializeBean
呼叫
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#a
pplyBeanPostProcessorsAfterInitialization
呼叫
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProce
ssAfterInitialization(后置處理器AbstractAutoProxyCreator完成bean代理物件創建)
呼叫
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNec
essary
呼叫
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#createPro
xy (在這一步把委托物件的aop增強和通用攔截進行合并,最終給代理物件)
呼叫
org.springframework.aop.framework.DefaultAopProxyFactory#createAopProxy
呼叫
org.springframework.aop.framework.CglibAopProxy#getProxy(java.lang.ClassLoader)
如果你需要這份完整版的《Spring高級原始碼筆記》,只需你多多支持我這篇文章,
多多支持,即可免費獲取資料——三連之后(承諾:100%免費)
快速入手通道:添加助理VX:C18173184271,備注一下CSDN+作業年限! 免費獲取!誠意滿滿!!!

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/253173.html
標籤:java
下一篇:關于用vs2017的問題

