Spring原始碼解析-aop
spring核心IOC和AOP,終於到aop,看起來真心費力。
demo
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ss="http://www.springframework.org/schema/security"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"
default-autowire="byName">
<aop:aspectj-autoproxy />
<bean id="test" class="qbb.aop.TestBean" />
<bean class="qbb.aop.AspectJTest" />
</beans>
public class TestBean {
private String testStr = "testStr";
public String getTestStr() {
return testStr;
}
public void setTestStr(String testStr) {
this.testStr = testStr;
}
public void cout(){
System.out.println("test");
}
}
@Aspect
public class AspectJTest {
@Pointcut("execution(* *.cout(..))")
public void test(){
}
@Before("test()")
public void beforeTest(){
System.out.println("beforeTest");
}
@After("test()")
public void afterTest(){
System.out.println("afterTest");
}
@Around("test()")
public Object arroundTest(ProceedingJoinPoint p){
System.out.println("before1");
Object o = null;
try {
o = p.proceed();
}catch (Throwable e){
e.printStackTrace();
}
System.out.println("after1");
return o;
}
}
test
public class AopTest {
public static void main(String[] args){
ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-aop.xml");
TestBean testBean = (TestBean) ctx.getBean("test");
testBean.cout();
}
}
aop自定義標籤分析
aop採用自定義標籤解析。
http\://www.springframework.org/schema/aop=org.springframework.aop.config.AopNamespaceHandler
http\://www.springframework.org/schema/aop/spring-aop-2.0.xsd=org/springframework/aop/config/spring-aop-2.0.xsd
http\://www.springframework.org/schema/aop/spring-aop-2.5.xsd=org/springframework/aop/config/spring-aop-2.5.xsd
http\://www.springframework.org/schema/aop/spring-aop-3.0.xsd=org/springframework/aop/config/spring-aop-3.0.xsd
http\://www.springframework.org/schema/aop/spring-aop-3.1.xsd=org/springframework/aop/config/spring-aop-3.1.xsd
http\://www.springframework.org/schema/aop/spring-aop.xsd=org/springframework/aop/config/spring-aop-3.1.xsd
標籤的處理AopNamespaceHandler:
//AopNamespaceHandler
public class AopNamespaceHandler extends NamespaceHandlerSupport {
public void init() {
// In 2.0 XSD as well as in 2.1 XSD.
//處理xml中的配置advisor
registerBeanDefinitionParser("config", new ConfigBeanDefinitionParser());
//註解的Aspect解析
registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser());
//下面2個沒用過
registerBeanDefinitionDecorator("scoped-proxy", new ScopedProxyBeanDefinitionDecorator());
// Only in 2.0 XSD: moved to context namespace as of 2.1
registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
}
}
之前自定義標籤看過,遇到自定義自定義標籤,首先uri找到namespacehandler,呼叫init方法註冊標籤的解析beanDefinitionparser,然後呼叫beanDefinitionParser的parser解析返回beanDefinition註冊到beanfactory裡面去。
aop這裡註冊了不同的標籤解析handler,主要看下aspectj-autoproxy的handlerAspectJAutoProxyBeanDefinitionParser。
//AspectJAutoProxyBeanDefinitionParser
public BeanDefinition parse(Element element, ParserContext parserContext) {
//解析aspectj-autoproxy標籤
AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext, element);
//解析子標籤
extendBeanDefinition(element, parserContext);
return null;
}
//AopNamespaceUtils
public static void registerAspectJAnnotationAutoProxyCreatorIfNecessary(
ParserContext parserContext, Element sourceElement) {
BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(
parserContext.getRegistry(), parserContext.extractSource(sourceElement));
//設定proxy-target-class和expose-proxy2個屬性
useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
//註冊元件,然後fire
registerComponentIfNecessary(beanDefinition, parserContext);
}
//AopConfigUtils
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) {
//註冊或升級解析bean:AnnotationAwareAspectJAutoProxyCreator
return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}
private static BeanDefinition registerOrEscalateApcAsRequired(Class cls, BeanDefinitionRegistry registry, Object source) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
//如果已經有,就比較優先順序,改變beanClassName
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;
}
RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
beanDefinition.setSource(source);
beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
//註冊beanDefinition,最終aop通過這個bean來實現
registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
return beanDefinition;
}
這裡只是註冊了一個解析bean,沒有真正實現aop的功能,功能實現通過註冊的bean:AnnotationAwareAspectJAutoProxyCreator在getbean的時候通過BeanPostProcessor實現。
AnnotationAwareAspectJAutoProxyCreator
AnnotationAwareAspectJAutoProxyCreator是實現了BeanPostProcessor(初始化前,初始化後處理器)和InstantiationAwareBeanPostProcessor(例項化前,例項化後處理器)2個介面來實現aop功能。
大致看下方法實現:
//AbstractAutoProxyCreator
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
Object cacheKey = getCacheKey(beanClass, beanName); //快取取現
if (!this.targetSourcedBeans.contains(cacheKey)) {
//是否處理過或者不需要
if (this.advisedBeans.contains(cacheKey) || this.nonAdvisedBeans.contains(cacheKey)) {
return null;
}
//是否基礎類或者跳過
//isInfrastructureClass判斷是否Advisor、Advice、AopInfrastructureBean
//shouldSkip子類實現,如果aspect切面類和要代理的類名相同,那就skip
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
this.nonAdvisedBeans.add(cacheKey);
return null;
}
}
// Create proxy here if we have a custom TargetSource.
// Suppresses unnecessary default instantiation of the target bean:
// The TargetSource will handle target instances in a custom fashion.
// 自定義的TargetSource,如果你需要在執行時,動態切換代理例項或者新生成一個,就可以試試這個玩意
TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
if (targetSource != null) {
this.targetSourcedBeans.add(beanName);
//獲取bean適配的Advice
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
//建立代理
Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
return null;
}
public boolean postProcessAfterInstantiation(Object bean, String beanName) {
return true;
}
public Object postProcessBeforeInitialization(Object bean, String beanName) {
return bean;
}
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey)) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
//是否需要aop解析
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (this.targetSourcedBeans.contains(beanName)) {
return bean;
}
if (this.nonAdvisedBeans.contains(cacheKey)) {
return bean;
}
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.nonAdvisedBeans.add(cacheKey);
return bean;
}
// Create proxy if we have advice.
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.add(cacheKey);
Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
this.nonAdvisedBeans.add(cacheKey);
return bean;
}
最重要的2個方法
//獲取適合的advise
getAdvicesAndAdvisorsForBean
//建立代理類
createProxy
getAdvicesAndAdvisorsForBean獲取適合的advise
//AbstractAdvisorAutoProxyCreator
protected Object[] getAdvicesAndAdvisorsForBean(Class beanClass, String beanName, TargetSource targetSource) {
List advisors = findEligibleAdvisors(beanClass, beanName);
if (advisors.isEmpty()) {
return DO_NOT_PROXY;
}
return advisors.toArray();
}
//獲取匹配的Advisor
protected List<Advisor> findEligibleAdvisors(Class beanClass, String beanName) {
//獲取所有Advisor
List<Advisor> candidateAdvisors = findCandidateAdvisors();
//獲取匹配的
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
邏輯清晰,首先獲取所有的advisor,然後找到匹配當前bean的advisor。
findCandidateAdvisors獲取所有的advisor
// AnnotationAwareAspectJAutoProxyCreator
// 獲取所有的advisor
protected List<Advisor> findCandidateAdvisors() {
// Add all the Spring advisors found according to superclass rules.
// 獲取xml裡面配置advisor
List<Advisor> advisors = super.findCandidateAdvisors();
// Build Advisors for all AspectJ aspects in the bean factory.
// 獲取aspect註解的advisor
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
return advisors;
}
findCandidateAdvisors獲取xml裡面配置的advisor分2步:
1. 從beanfactory中獲取beanNameType為Advisor的所有beanNames;
2. 從beanfactory中getBean,建立這些advisor的bean。
buildAspectJAdvisors獲取註解Aspect的advisor
// BeanFactoryAspectJAdvisorsBuilder
// 獲取註解Aspect的advisor
public List<Advisor> buildAspectJAdvisors() {
List<String> aspectNames = null;
synchronized (this) {
aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
List<Advisor> advisors = new LinkedList<Advisor>();
aspectNames = new LinkedList<String>();
String[] beanNames =
BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, Object.class, true, false);
for (String beanName : beanNames) {
if (!isEligibleBean(beanName)) {
continue;
}
// We must be careful not to instantiate beans eagerly as in this
// case they would be cached by the Spring container but would not
// have been weaved
Class beanType = this.beanFactory.getType(beanName);
if (beanType == null) {
continue;
}
// 過濾型別必須為Aspect型別
if (this.advisorFactory.isAspect(beanType)) {
aspectNames.add(beanName);
// AspectMetadata是aspect的元資料
AspectMetadata amd = new AspectMetadata(beanType, beanName);
// 預設就是SINGLETON
if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
// factory的實現可以保證AspectMetadata例項化一次
MetadataAwareAspectInstanceFactory factory =
new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
// 獲取註解Aspect的advisor
List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
if (this.beanFactory.isSingleton(beanName)) {
this.advisorsCache.put(beanName, classAdvisors);
}
else {
this.aspectFactoryCache.put(beanName, factory);
}
advisors.addAll(classAdvisors);
}
else {
// Per target or per this.
if (this.beanFactory.isSingleton(beanName)) {
throw new IllegalArgumentException("Bean with name '" + beanName +
"' is a singleton, but aspect instantiation model is not singleton");
}
MetadataAwareAspectInstanceFactory factory =
new PrototypeAspectInstanceFactory(this.beanFactory, beanName);
this.aspectFactoryCache.put(beanName, factory);
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
}
this.aspectBeanNames = aspectNames;
return advisors;
}
}
if (aspectNames.isEmpty()) {
return Collections.EMPTY_LIST;
}
//如果已經處理過了,直接從快取取
List<Advisor> advisors = new LinkedList<Advisor>();
for (String aspectName : aspectNames) {
List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
if (cachedAdvisors != null) {
advisors.addAll(cachedAdvisors);
}
else {
MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
return advisors;
}
首先看是否解析過Aspect元資料,沒解析過就重頭開始,解析過就從快取裡面取wrap的factory,獲取advisor。
getAdvisors
//ReflectiveAspectJAdvisorFactory
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory maaif) {
// 都是通過Aspect元資料的來解析,解析標記Aspect的類的class
final Class<?> aspectClass = maaif.getAspectMetadata().getAspectClass();
// 獲取name
final String aspectName = maaif.getAspectMetadata().getAspectName();
// 校驗aspect類的是否有註解Aspect,為Singleton
validate(aspectClass);
// We need to wrap the MetadataAwareAspectInstanceFactory with a decorator
// so that it will only instantiate once.
// 保證元資料Aspect生成的例項唯一
final MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
new LazySingletonAspectInstanceFactoryDecorator(maaif);
final List<Advisor> advisors = new LinkedList<Advisor>();
// doWithMethods的時候不但解析本Aspect,如果有Superclass,也會,如果不是superlclass,是介面的話,解析所有介面的
ReflectionUtils.doWithMethods(aspectClass, new ReflectionUtils.MethodCallback() {
public void doWith(Method method) throws IllegalArgumentException {
// Exclude pointcuts
// 不解析pointCut註解,這個註解是在匹配canApplay的getClassFilter過濾時處理
if (AnnotationUtils.getAnnotation(method, Pointcut.class) == null) {
// 解析方法上的advisor
Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);
if (advisor != null) {
advisors.add(advisor);
}
}
}
});
// If it's a per target aspect, emit the dummy instantiating aspect.
// advisor不為空,且配置的是延遲初始化,加入同步例項化advisor
if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
advisors.add(0, instantiationAdvisor);
}
// Find introduction fields.
// declareParents註解
for (Field field : aspectClass.getDeclaredFields()) {
Advisor advisor = getDeclareParentsAdvisor(field);
if (advisor != null) {
advisors.add(advisor);
}
}
return advisors;
}
看到處理方式是對Aspect類的非pointcut方法進行解析:
//ReflectiveAspectJAdvisorFactory
public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aif,
int declarationOrderInAspect, String aspectName) {
validate(aif.getAspectMetadata().getAspectClass());
// 方法註解上的註解表示式
// 註解:Before, Around, After, AfterReturning, AfterThrowing, Pointcut
AspectJExpressionPointcut ajexp =
getPointcut(candidateAdviceMethod, aif.getAspectMetadata().getAspectClass());
if (ajexp == null) {
return null;
}
// 封裝advisor,構造會區分不同註解的Advice
return new InstantiationModelAwarePointcutAdvisorImpl(
this, ajexp, aif, candidateAdviceMethod, declarationOrderInAspect, aspectName);
}
//獲取註解表示式
private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) {
// 註解:Before, Around, After, AfterReturning, AfterThrowing, Pointcut
AspectJAnnotation<?> aspectJAnnotation =
AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
if (aspectJAnnotation == null) {
return null;
}
// 解析註解表示式,只是單純註解上表達式,不會關聯pointcut
AspectJExpressionPointcut ajexp =
new AspectJExpressionPointcut(candidateAspectClass, new String[0], new Class[0]);
ajexp.setExpression(aspectJAnnotation.getPointcutExpression());
return ajexp;
}
注意在解析method上註解表示式後會根據統一封裝成InstantiationModelAwarePointcutAdvisorImpl,該類的構造會區分不同的Advice:
// ReflectiveAspectJAdvisorFactory
public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut ajexp,
MetadataAwareAspectInstanceFactory aif, int declarationOrderInAspect, String aspectName) {
Class<?> candidateAspectClass = aif.getAspectMetadata().getAspectClass();
validate(candidateAspectClass);
AspectJAnnotation<?> aspectJAnnotation =
AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
if (aspectJAnnotation == null) {
return null;
}
...
AbstractAspectJAdvice springAdvice;
switch (aspectJAnnotation.getAnnotationType()) {
case AtBefore:
springAdvice = new AspectJMethodBeforeAdvice(candidateAdviceMethod, ajexp, aif);
break;
case AtAfter:
springAdvice = new AspectJAfterAdvice(candidateAdviceMethod, ajexp, aif);
break;
case AtAfterReturning:
springAdvice = new AspectJAfterReturningAdvice(candidateAdviceMethod, ajexp, aif);
AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation();
if (StringUtils.hasText(afterReturningAnnotation.returning())) {
springAdvice.setReturningName(afterReturningAnnotation.returning());
}
break;
case AtAfterThrowing:
springAdvice = new AspectJAfterThrowingAdvice(candidateAdviceMethod, ajexp, aif);
AfterThrowing afterThrowingAnnotation = (AfterThrowing) aspectJAnnotation.getAnnotation();
if (StringUtils.hasText(afterThrowingAnnotation.throwing())) {
springAdvice.setThrowingName(afterThrowingAnnotation.throwing());
}
break;
case AtAround:
springAdvice = new AspectJAroundAdvice(candidateAdviceMethod, ajexp, aif);
break;
case AtPointcut:
if (logger.isDebugEnabled()) {
logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
}
return null;
default:
throw new UnsupportedOperationException(
"Unsupported advice type on method " + candidateAdviceMethod);
}
// Now to configure the advice...
springAdvice.setAspectName(aspectName);
springAdvice.setDeclarationOrder(declarationOrderInAspect);
String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
if (argNames != null) {
springAdvice.setArgumentNamesFromStringArray(argNames);
}
springAdvice.calculateArgumentBindings();
return springAdvice;
}
不同的註解對應不同的封裝。雖然都是Advice的封裝,但是AspectJMethodBeforeAdvice、AspectJAfterReturningAdvice不是通過MethodInterceptor實現,其他幾個是通過MethodInterceptor的invoke實現,
不過最後的最後所有Advice都會統一封裝成MethodInterceptor的實現類。
記得一點:所有的Advice最後都會封裝成MethodInterceptor實現類。
findAdvisorsThatCanApply匹配當前bean的advisor
// AbstractAdvisorAutoProxyCreator
protected List<Advisor> findAdvisorsThatCanApply(
List<Advisor> candidateAdvisors, Class beanClass, String beanName) {
ProxyCreationContext.setCurrentProxiedBeanName(beanName);
try {
// 在找到所有advisor後,再查詢匹配當前要代理bean的advisor
return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
}
finally {
ProxyCreationContext.setCurrentProxiedBeanName(null);
}
}
// AopUtils
public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
if (candidateAdvisors.isEmpty()) {
return candidateAdvisors;
}
List<Advisor> eligibleAdvisors = new LinkedList<Advisor>();
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;
}
// 匹配
if (canApply(candidate, clazz, hasIntroductions)) {
eligibleAdvisors.add(candidate);
}
}
return eligibleAdvisors;
}
// 查詢是否匹配
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) {
// 一般的advisor
PointcutAdvisor pca = (PointcutAdvisor) advisor;
return canApply(pca.getPointcut(), targetClass, hasIntroductions);
}
else {
// It doesn't have a pointcut so we assume it applies.
return true;
}
}
裡面有個特殊的引介IntroductionAdvisor,當已經有一個類,你想在執行時動態的為這個類增加一些執行方法(相當於又實現了其他介面方法),就可以嘗試引介advisor。
canApply
// AopUtils
public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
// 在getClassFilter呼叫中buildPointcutExpression方法完成PointCut註解的解析,這裡是匹配類級別
if (!pc.getClassFilter().matches(targetClass)) {
return false;
}
MethodMatcher methodMatcher = pc.getMethodMatcher();
IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
}
// 獲取目標代理類的所有實現介面
Set<Class> classes = new HashSet<Class>(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
classes.add(targetClass);
for (Class<?> clazz : classes) {
Method[] methods = clazz.getMethods();
for (Method method : methods) {
// 匹配方法級
if ((introductionAwareMethodMatcher != null &&
introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions)) ||
methodMatcher.matches(method, targetClass)) {
return true;
}
}
}
return false;
}
這裡首先完成pointcut註解的解析,然後匹配類級別,然後對目標類的每個實現方法,完成方法級別的匹配,裡面太複雜,看了幾遍,還是有些細節沒把握好。
createProxy建立代理類
在找到目標類的所有匹配的advisor後,開始建立代理物件。
// AbstractAutoProxyCreator
protected Object createProxy(
Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {
ProxyFactory proxyFactory = new ProxyFactory();
// Copy our properties (proxyTargetClass etc) inherited from ProxyConfig.
// 複製一些屬性 other.optimize; proxyTargetClass\optimize\exposeProxy\frozen\opaque
proxyFactory.copyFrom(this);
// 給定的bean是否使用targetClass作為target還是介面代理
// 基本是proxyTargetClass和bean配置的preserveTargetClass2個屬性值
if (!shouldProxyTargetClass(beanClass, beanName)) {
// Must allow for introductions; can't just set interfaces to
// the target's interfaces only.
// 加入所有實現介面
Class<?>[] targetInterfaces = ClassUtils.getAllInterfacesForClass(beanClass, this.proxyClassLoader);
for (Class<?> targetInterface : targetInterfaces) {
proxyFactory.addInterface(targetInterface);
}
}
// 對之前匹配的advisor處理下
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
for (Advisor advisor : advisors) {
proxyFactory.addAdvisor(advisor);
}
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory); //子類實現,可以更改一些設定
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
// 獲取代理
return proxyFactory.getProxy(this.proxyClassLoader);
}
buildAdvisors
// AbstractAutoProxyCreator
protected Advisor[] buildAdvisors(String beanName, Object[] specificInterceptors) {
// Handle prototypes correctly...
// 解析this.interceptorNames中的Advisor,通過beanName獲取bean,加到advisor裡面,說實話,暫時沒看到有呼叫設定的地方,可以pass先
// 可以配置一些通用的
Advisor[] commonInterceptors = resolveInterceptorNames();
List<Object> allInterceptors = new ArrayList<Object>();
if (specificInterceptors != null) {
// 當前匹配的
allInterceptors.addAll(Arrays.asList(specificInterceptors));
if (commonInterceptors != null) {
if (this.applyCommonInterceptorsFirst) {
allInterceptors.addAll(0, Arrays.asList(commonInterceptors));
}
else {
allInterceptors.addAll(Arrays.asList(commonInterceptors));
}
}
}
if (logger.isDebugEnabled()) {
int nrOfCommonInterceptors = (commonInterceptors != null ? commonInterceptors.length : 0);
int nrOfSpecificInterceptors = (specificInterceptors != null ? specificInterceptors.length : 0);
logger.debug("Creating implicit proxy for bean '" + beanName + "' with " + nrOfCommonInterceptors +
" common interceptors and " + nrOfSpecificInterceptors + " specific interceptors");
}
Advisor[] advisors = new Advisor[allInterceptors.size()];
for (int i = 0; i < allInterceptors.size(); i++) {
// wrap操作:統一封裝成advisor
advisors[i] = this.advisorAdapterRegistry.wrap(allInterceptors.get(i));
}
return advisors;
}
// DefaultAdvisorAdapterRegistry
// 將攔截器,advisor、advice什麼的都統一封裝成advisor先
public Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException {
if (adviceObject instanceof Advisor) {
return (Advisor) adviceObject;
}
if (!(adviceObject instanceof Advice)) {
throw new UnknownAdviceTypeException(adviceObject);
}
Advice advice = (Advice) adviceObject;
if (advice instanceof MethodInterceptor) {
// So well-known it doesn't even need an adapter.
return new DefaultPointcutAdvisor(advice);
}
for (AdvisorAdapter adapter : this.adapters) {
// Check that it is supported.
if (adapter.supportsAdvice(advice)) {
return new DefaultPointcutAdvisor(advice);
}
}
throw new UnknownAdviceTypeException(advice);
}
可以認為buildAdvisors,這一步是將所有攔截器、advisor、Advice什麼的都統一封裝成Advisor,方便後面處理。
getProxy建立代理物件
// ProxyFactory
public Object getProxy(ClassLoader classLoader) {
// 建立代理,生成代理物件
return createAopProxy().getProxy(classLoader);
}
createAopProxy建立代理
// ProxyFactory
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
return getAopProxyFactory().createAopProxy(this);
}
// DefaultAopProxyFactory
// 決定是jdk代理還是cglib代理
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);
}
if (!cglibAvailable) {
throw new AopConfigException(
"Cannot proxy target class because CGLIB2 is not available. " +
"Add CGLIB to the class path or specify proxy interfaces.");
}
return CglibProxyFactory.createCglibProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
這裡主要是決定是jdk代理還是cglib代理。 jdk只能代理介面,所以如果目標類有實現介面的情況,aop配置proxyTargetClass=true,那就cglib,否則jdk代理,沒有實現介面,那隻能cglib代理。
JdkDynamicAopProxy
jdk動態代理通過InvocationHandler的invoke方法。
// JdkDynamicAopProxy
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
MethodInvocation invocation;
Object oldProxy = null;
boolean setProxyContext = false;
TargetSource targetSource = this.advised.targetSource;
Class targetClass = null;
Object target = null;
try {
// equals\hashCode方法,內部直接呼叫返回
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
// The target does not implement the equals(Object) method itself.
return equals(args[0]);
}
if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
// The target does not implement the hashCode() method itself.
return hashCode();
}
if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
method.getDeclaringClass().isAssignableFrom(Advised.class)) {
// Service invocations on ProxyConfig with the proxy config...
return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
}
Object retVal;
// 內部呼叫是否攔截,通過配置exposeProxy控制
if (this.advised.exposeProxy) {
// Make invocation available if necessary.
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
// May be null. Get as late as possible to minimize the time we "own" the target,
// in case it comes from a pool.
target = targetSource.getTarget();
if (target != null) {
targetClass = target.getClass();
}
// Get the interception chain for this method.
// 所有攔截器-會將之前沒有實現MethodInterceptor的advice全部轉為實現該介面的類
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
// Check whether we have any advice. If we don't, we can fallback on direct
// reflective invocation of the target, and avoid creating a MethodInvocation.
if (chain.isEmpty()) {
// We can skip creating a MethodInvocation: just invoke the target directly
// Note that the final invoker must be an InvokerInterceptor so we know it does
// nothing but a reflective operation on the target, and no hot swapping or fancy proxying.
// 攔截器鏈空,直接呼叫
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, args);
}
else {
// We need to create a method invocation...
invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
// Proceed to the joinpoint through the interceptor chain.
// 攔截器鏈呼叫
retVal = invocation.proceed();
}
// Massage return value if necessary.
if (retVal != null && retVal == target && method.getReturnType().isInstance(proxy) &&
!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
// Special case: it returned "this" and the return type of the method
// is type-compatible. Note that we can't help if the target sets
// a reference to itself in another returned object.
retVal = proxy;
}
return retVal;
}
finally {
if (target != null && !targetSource.isStatic()) {
// Must have come from TargetSource.
targetSource.releaseTarget(target);
}
if (setProxyContext) {
// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);
}
}
}
getInterceptorsAndDynamicInterceptionAdvice
這一步主要是回去方法匹配的攔截器鏈。
// DefaultAdvisorChainFactory
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
Advised config, Method method, Class targetClass) {
// This is somewhat tricky... we have to process introductions first,
// but we need to preserve order in the ultimate list.
List<Object> interceptorList = new ArrayList<Object>(config.getAdvisors().length);
boolean hasIntroductions = hasMatchingIntroductions(config, targetClass);
AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
// 對所有advisor迴圈判斷
for (Advisor advisor : config.getAdvisors()) {
if (advisor instanceof PointcutAdvisor) {
// Add it conditionally.
PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
// 類是否匹配
if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(targetClass)) {
// 這裡做轉換,沒有實現methodInterceptor的做適配
MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
// 方法是否匹配