docs/Spring全家桶/Spring源码分析/SpringAOP/AnnotationAwareAspectJAutoProxyCreator分析(下).md
һƪҪ AbstractAutoProxyCreator#postProcessAfterInitialization AbstractAutoProxyCreator#postProcessAfterInitialization
ĵ
|-AnnotationConfigApplicationContext
|-AbstractApplicationContext#refresh
|-AbstractApplicationContext#finishBeanFactoryInitialization
|-ConfigurableListableBeanFactory#preInstantiateSingletons
|-AbstractBeanFactory#getBean(String)
|-AbstractBeanFactory#doGetBean
|-DefaultSingletonBeanRegistry#getSingleton(String, ObjectFactory<?>)
|-ObjectFactory#getObject
|-AbstractBeanFactory#createBean
|-AbstractAutowireCapableBeanFactory#doCreateBean
|-AbstractAutowireCapableBeanFactory#initializeBean(String, Object, RootBeanDefinition)
|-AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization
|-AbstractAutoProxyCreator#postProcessAfterInitialization
ʵĵ spring bean Ĵ̣ǽ AbstractAutoProxyCreator#postProcessAfterInitialization
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
// wrapIfNecessary()
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
AbstractAutoProxyCreator#wrapIfNecessary
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;
}
е㳤붼жϣ aop ܹϵйϵĴֻУ
// Ҫһ
// 1\. isInfrastructureClassжϵǰǷΪaop࣬
// Advice/Pointcut/Advisorȵ࣬Ƿ @AspectJע
// 2\. shouldSkip࣬жǷų
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
...
}
// ҪУǷӦñȡǿ
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
// Ҫ
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
ҪһһƪѾҪҪ``Ҫ
AbstractAdvisorAutoProxyCreator
@Override
@Nullable
protected Object[] getAdvicesAndAdvisorsForBean(
Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
// ҷǿ¿
List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
if (advisors.isEmpty()) {
return DO_NOT_PROXY;
}
return advisors.toArray();
}
/**
* ҷǿ
*/
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
//ȡеǿһƪѾ
List<Advisor> candidateAdvisors = findCandidateAdvisors();
//֤beanClassǷñӦãbeanǿ
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
/**
* ֤beanClassǷñ
*/
protected List<Advisor> findAdvisorsThatCanApply(
List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {
ProxyCreationContext.setCurrentProxiedBeanName(beanName);
try {
// ֤beanClassǷñ
return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
}
finally {
ProxyCreationContext.setCurrentProxiedBeanName(null);
}
}
spring ķñȽһ·٣յ AopUtils.findAdvisorsThatCanApply ¿
AopUtils
public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
if (candidateAdvisors.isEmpty()) {
return candidateAdvisors;
}
List<Advisor> eligibleAdvisors = new ArrayList<>();
// candidateAdvisorsжǷ
for (Advisor candidate : candidateAdvisors) {
//ǿص㣬¿
if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
eligibleAdvisors.add(candidate);
}
}
boolean hasIntroductions = !eligibleAdvisors.isEmpty();
for (Advisor candidate : candidateAdvisors) {
if (candidate instanceof IntroductionAdvisor) {
// already processed
continue;
}
//ͨbeanĴ
if (canApply(candidate, clazz, hasIntroductions)) {
eligibleAdvisors.add(candidate);
}
}
return eligibleAdvisors;
}
/**
* жǷҪǿ
*/
public static boolean canApply(Advisor advisor, Class<?> targetClass) {
// һ
return canApply(advisor, targetClass, false);
}
/**
* жǷҪǿ
*/
public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
//ų
if (advisor instanceof IntroductionAdvisor) {
return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);
}
else if (advisor instanceof PointcutAdvisor) {
PointcutAdvisor pca = (PointcutAdvisor) advisor;
//÷
return canApply(pca.getPointcut(), targetClass, hasIntroductions);
}
else {
// It doesn't have a pointcut so we assume it applies.
return true;
}
}
/**
* жǷҪǿ
*/
public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
Assert.notNull(pc, "Pointcut must not be null");
//еǷų
if (!pc.getClassFilter().matches(targetClass)) {
return false;
}
//֤עǷڷ
MethodMatcher methodMatcher = pc.getMethodMatcher();
if (methodMatcher == MethodMatcher.TRUE) {
// No need to iterate the methods if we're matching any method anyway...
return true;
}
IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
}
// classestargetClassObjectиࡢнӿ
Set<Class<?>> classes = new LinkedHashSet<>();
if (!Proxy.isProxyClass(targetClass)) {
classes.add(ClassUtils.getUserClass(targetClass));
}
classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
// ѭжϷǷҪ
// Կ
// 1\. ֻҪһҪôͻᱻ
// 2\. зҪôҲᱻ
for (Class<?> clazz : classes) {
// ȡ clazz ķ
// ǰķObjectиӿڵĬϷ
Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
for (Method method : methods) {
//ȡʵֵнӿں㼶ķѭ֤
if (introductionAwareMethodMatcher != null ?
introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :
methodMatcher.matches(method, targetClass)) {
return true;
}
}
}
return false;
}
Ͼ˽ spring жһǷҪģܽ£
List<Advisor>һƪϸAdvisorÿһ Advisor÷ȡǰij Object и༰ӿڣΪ Set<Class>Set<Class>ÿһ Class÷ȡ Class Object иķӿڵĬϷΪ Method[];Method[]һ method Advisor ʾǰ Advisor Ӧõǰ bean bean ҪһյõĽҲһ List<Advisor>ʾж Advisor ҪӦõöαڣ
// 1\. ȡеAdvisor
List<Advisor> advisorList = getAdvisorList();
// 2\. Advisor
for(Advisor advisor : advisorList) {
// ȡǰij`Object`и༰ӿڣclassSetҲtargetClass
Set<Class> classSet = getSuperClassAndInterfaces(targetClass);
for(Class cls : classSet) {
// clsжķǰķObjectиӿڵĬϷ
Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
// Щ
for (Method method : methods) {
// жmethodǷ
}
}
}
õ List<Advisor> Ǹ List<Advisor> ˡ
spring ̡
AbstractAutoProxyCreator#wrapIfNecessary
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
...
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
// ﴴ
// - specificInterceptorsӦõö Advisor
// specificInterceptorsĻȡ̣һѾϸˣ
// - SingletonTargetSourceԭʼһװ
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;
}
SingletonTargetSource
public class SingletonTargetSource implements TargetSource, Serializable {
private static final long serialVersionUID = 9031246629662423738L;
private final Object target;
public SingletonTargetSource(Object target) {
Assert.notNull(target, "Target object must not be null");
this.target = target;
}
@Override
public Class<?> getTargetClass() {
return this.target.getClass();
}
@Override
public Object getTarget() {
return this.target;
}
...
}
ܼǶԭʼһװ¿
AbstractAutoProxyCreator#createProxy
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();
//ʹproxyFactorycopyǰе
proxyFactory.copyFrom(this);
// жǷʹCglib̬עָ
// @EnableAspectJAutoProxy(proxyTargetClass = true)
if (!proxyFactory.isProxyTargetClass()) {
// beanFactory ConfigurableListableBeanFactory
// BeanDefinition ԣijһʹ cglib
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
// ûÿ, жbeanǷкʵĽӿʹJDKĶ̬
// ע⣺JDK̬Ǵнӿڵ
// ûʵκνӿֻʹCglib̬
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
// Advisor
// 1\. ӹ Interceptor
// 2\. ڸadvisorжͣȻתΪ
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
//ǿ
proxyFactory.addAdvisors(advisors);
//Ҫ
proxyFactory.setTargetSource(targetSource);
//Springһչ㣬ĬʵΪաҪԴʱʵ
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
//ʹôȡ
return proxyFactory.getProxy(getProxyClassLoader());
}
@EnableAspectJAutoProxy עУʹ proxyTargetClass = true Ŀʹ cglib ڴҲ֣
// ֻproxyFactory.isProxyTargetClass()ΪfalseʱŻж
// ֮ @EnableAspectJAutoProxy(proxyTargetClass = true) ʱ
// ĴDzеģĬʹþcglib
if (!proxyFactory.isProxyTargetClass()) {
// жû BeanDefinition ʹ cglib
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
// ǷӿڵǷjdk̬
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
spring жһǷ jdk ̬أ֪˵ʵ˽ӿڣͿʹöֻ̬ʹ cglib spring жϵģ
ProxyProcessorSupport#evaluateProxyInterfaces
/**
* жǷʹjdk̬
*/
protected void evaluateProxyInterfaces(Class<?> beanClass, ProxyFactory proxyFactory) {
// ȡнӿ
Class<?>[] targetInterfaces = ClassUtils.getAllInterfacesForClass(beanClass, getProxyClassLoader());
boolean hasReasonableProxyInterface = false;
for (Class<?> ifc : targetInterfaces) {
// 1.isConfigurationCallbackInterface: жifcǷΪInitializingBeanDisposableBean
// CloseableAutoCloseableԼ Aware
// 2.isInternalLanguageInterface: ǷΪڲԽӿڣgroovymock
// 3.ifc.getMethods().length > 0ӿڵķ1
if (!isConfigurationCallbackInterface(ifc) && !isInternalLanguageInterface(ifc) &&
ifc.getMethods().length > 0) {
hasReasonableProxyInterface = true;
break;
}
}
if (hasReasonableProxyInterface) {
// ҪеĽӿڶõproxyFactory
// һ£һA ʵ˽ӿ I1 I2
// AĶa йܵspringôʹ beanFactory.get(I1.class)
// beanFactory.get(I1.class)Ӧܻȡa.
for (Class<?> ifc : targetInterfaces) {
proxyFactory.addInterface(ifc);
}
}
else {
proxyFactory.setProxyTargetClass(true);
}
}
Դspring жǷʹ jdk ̬Ĺ֪ϵIJ࣬ʵӿھʹ jdk ̬spring ų InitializingBean``DisposableBean``Closeable``AutoCloseable ȽӿڣͬʱҲųκηĽӿڡ
spring жǷʹ jdk ̬ӿ spring δġΪ˵⣬ȼ AbstractAutoProxyCreator#createProxy
protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
@Nullable Object[] specificInterceptors, TargetSource targetSource) {
// ʡһЩ
...
ProxyFactory proxyFactory = new ProxyFactory();
//ʹproxyFactorycopyǰе
proxyFactory.copyFrom(this);
// ʡ˺öж
proxyFactory.setProxyTargetClass(true);
//ǿ
proxyFactory.addAdvisors(advisors);
//Ҫ
proxyFactory.setTargetSource(targetSource);
...
//ʹôȡ
return proxyFactory.getProxy(getProxyClassLoader());
}
Կһ ProxyFactory ȻöһЩֵ¿
ProxyFactory#getProxy(java.lang.ClassLoader)
public Object getProxy(@Nullable ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader);
}
createAopProxy() getProxy(classLoader) createAopProxy()
ProxyCreatorSupport#createAopProxy
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
return getAopProxyFactory().createAopProxy(this);
}
DefaultAopProxyFactory#createAopProxy
/**
* жϴ
* ʹjdk̬ͷ JdkDynamicAopProxy
* ͷ ObjenesisCglibAopProxy
*/
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
Class<?> targetClass = config.getTargetClass();
if (targetClass == null) {
throw new AopConfigException(...);
}
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
ǾףJdkDynamicAopProxy jdk ̬ģObjenesisCglibAopProxy cglib ġ getProxy(classLoader)
JdkDynamicAopProxy#getProxy(java.lang.ClassLoader)
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
Class<?>[] proxiedInterfaces = AopProxyUtils
.completeProxiedInterfaces(this.advised, true);
// Ƿequals()hashCode()
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
// jdk
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
õĴʲôģ
Կ h Աľ JdkDynamicAopProxy JdkDynamicAopProxy advised Ա˴ĴϢ
CglibAopProxy#getProxy(java.lang.ClassLoader)
public Object getProxy(@Nullable ClassLoader classLoader) {
try {
Class<?> rootClass = this.advised.getTargetClass();
Assert.state(rootClass != null, "xxx");
Class<?> proxySuperClass = rootClass;
if (rootClass.getName().contains(ClassUtils.CGLIB_CLASS_SEPARATOR)) {
proxySuperClass = rootClass.getSuperclass();
Class<?>[] additionalInterfaces = rootClass.getInterfaces();
for (Class<?> additionalInterface : additionalInterfaces) {
this.advised.addInterface(additionalInterface);
}
}
validateClassIfNecessary(proxySuperClass, classLoader);
// Enhancer setһЩ
Enhancer enhancer = createEnhancer();
if (classLoader != null) {
enhancer.setClassLoader(classLoader);
if (classLoader instanceof SmartClassLoader &&
((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
enhancer.setUseCache(false);
}
}
// SuperclassҪ
enhancer.setSuperclass(proxySuperClass);
// ýӿڣ SpringProxyAdvised
enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(classLoader));
Callback[] callbacks = getCallbacks(rootClass);
Class<?>[] types = new Class<?>[callbacks.length];
for (int x = 0; x < types.length; x++) {
types[x] = callbacks[x].getClass();
}
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(...);
}
catch (Throwable ex) {
throw new AopConfigException("Unexpected AOP exception", ex);
}
}
spring ʹ cglib Ҫõ Enhancer ࣬һٷ
ҲõĶ
Ҫ AbstractAutoProxyCreator#postProcessAfterInitialization÷Ҫ£
ListʵϣһIJҲ AbstractAutoProxyCreator#postProcessBeforeInitialization ִУȻһʵֱڻýList ҲװСԭӣhttps://my.oschina.net/funcy/blog/4687961 ߸ˮƽд֮ӭָԭףҵתϵȨҵתע