前言
AOP是什么,在我看来,先别提切面、织入这些概念性的东西。用通俗一点的话来说就是:在某个方法的前后,动态地插入我们自己的逻辑。当然,AOP的相关概念还是非常多的,在了解AOP之前,我们先来看下它有什么作用。
一. AOP的使用
这次的案例,我也不准备在Spring源码项目上建立了,直接自己新建了个项目,结构如下: 1.pom 依赖:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.3.3</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.3</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.2.9.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.3.16</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
<scope>test</scope>
</dependency>
2.用于拦截的Bean :
public class TestBean {
private String testStr = "Hello";
public String getTestStr() {
return testStr;
}
public void setTestStr(String testStr) {
this.testStr = testStr;
}
public void test() {
System.out.println("test");
}
}
3.创建AspectJTest 类:
@Aspect
public class AspectJTest {
@Pointcut("execution(* *.test(..))")
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 arountTest(ProceedingJoinPoint p) {
System.out.println("AroundBefore");
Object o = null;
try {
o = p.proceed();
} catch (Throwable e) {
e.printStackTrace();
}
System.out.println("AroundAfter");
return o;
}
}
4.Test 类:
public class Test {
@org.junit.Test
public void test(){
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("test/test.xml");
TestBean bean = (TestBean) context.getBean("testBean");
bean.test();
}
}
5.test.xml 文件:
<?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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<aop:aspectj-autoproxy/>
<bean name="testBean" class="com.TestBean"/>
<bean class="com.AspectJTest"/>
</beans>
运行结果如下:
上述代码主要做了这么几件事:
- 在所有类的
test 方法执行前后分别打印BeforeTest 、AfterTest 信息。 - 在所有类的方法执行前后又以环绕的方式,打印了
AroundBefore 、AroundAfter 信息。
从代码上我们可以知道,我们使用了@Aspect 注解,同时XML 配置文件中又有这段配置声明:
<aop:aspectj-autoproxy/>
之后,我们来看下AOP是如何实现的。
二. AOP的实现
我们来看下AOP的调用入口AopNamespaceHandler :
public class AopNamespaceHandler extends NamespaceHandlerSupport {
@Override
public void init() {
registerBeanDefinitionParser("config", new ConfigBeanDefinitionParser());
registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser());
registerBeanDefinitionDecorator("scoped-proxy", new ScopedProxyBeanDefinitionDecorator());
registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
}
}
此时可以看到,在Spring解析配置文件的时候,遇到aspectj-autoproxy 注解,就会使用解析器AspectJAutoProxyBeanDefinitionParser 进行解析。
2.1 创建AnnotationAwareAspectJAutoProxyCreator
首先,Spring的解析器都是接口BeanDefinitionParser 的实现,而该接口中只定义了一个方法parse() ,因此其也是我们研究的入口函数,我们来看下AspectJAutoProxyBeanDefinitionParser.parse() 方法:
class AspectJAutoProxyBeanDefinitionParser implements BeanDefinitionParser {
@Override
@Nullable
public BeanDefinition parse(Element element, ParserContext parserContext) {
AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext, element);
extendBeanDefinition(element, parserContext);
return null;
}
}
我们来看下第一步中对于AnnotationAwareAspectJAutoProxyCreator 的注册步骤:
public static void registerAspectJAnnotationAutoProxyCreatorIfNecessary(
ParserContext parserContext, Element sourceElement) {
BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(
parserContext.getRegistry(), parserContext.extractSource(sourceElement));
useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
registerComponentIfNecessary(beanDefinition, parserContext);
}
紧接着,对这三点进行分别讲解:
2.1.1 注册或升级AnnotationAwareAspectJAutoProxyCreator
首先呢,我们先来说下AnnotationAwareAspectJAutoProxyCreator 是干啥用的,它可以根据@Point 注解定义的切点来自动代理相匹配的bean 。 也因此AOP的实现,基本上都是靠它来完成的。
咱们正常开发过程中,以AOP的使用为例。无非使用方式有两种:
那本文主要围绕着XML 配置来进行,从配置到现在,我们知道AOP的实现离不开AnnotationAwareAspectJAutoProxyCreator 类。那好,这里我让大家看看,注解方式的配置和AnnotationAwareAspectJAutoProxyCreator 又咋联系起来的。
首先,我们注解往往使用@EnableAspectJAutoProxy 来标识AOP功能的启用,我们来看下该注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
}
这里通过@Import 注解导入了AspectJAutoProxyRegistrar 类,
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
}
}
可见无论是XML 配置还是注解配置,都离不开AnnotationAwareAspectJAutoProxyCreator 类的帮助,好了,言归正传,我们来看下具体的注册或者升级流程做了什么事情:
public abstract class AopConfigUtils {
@Nullable
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(
BeanDefinitionRegistry registry, @Nullable Object source) {
return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}
↓↓↓↓↓↓
@Nullable
private static BeanDefinition registerOrEscalateApcAsRequired(
Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
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);
registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
return beanDefinition;
}
}
这段代码的作用其实也就是对AnnotationAwareAspectJAutoProxyCreator 类的一个注册,对于其作用将在后文展开。接下来看下第二步。
2.1.2 处理 proxy-target-class 以及 expose-proxy 属性
入口函数如下:
useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
↓↓↓↓↓
private static void useClassProxyingIfNecessary(BeanDefinitionRegistry registry, @Nullable Element sourceElement) {
if (sourceElement != null) {
boolean proxyTargetClass = Boolean.parseBoolean(sourceElement.getAttribute(PROXY_TARGET_CLASS_ATTRIBUTE));
if (proxyTargetClass) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
boolean exposeProxy = Boolean.parseBoolean(sourceElement.getAttribute(EXPOSE_PROXY_ATTRIBUTE));
if (exposeProxy) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
注意:
- 若被代理的对象实现了至少一个接口,那么会使用
JDK动态代理 。同时所有该目标实现的接口都会被代理。 - 若该对象没有实现任何接口,那么创建一个
Cglib 代理。
开启Cglib 代理的方式如下:
<aop:aspectj-autoproxy proxy-target-class="true"/>
那么两者有啥区别呢?
JDK动态代理 :其代理对象必须是某个接口的实现,它通过在运行期间创建一个接口的实现类来完成对目标对象的代理。Cglib代理 :在运行期间生成的代理对象为针对目标类扩展的子类。底层通过ASM操作字节码来实现,性能比JDK代理强。
注册组件通知就不再赘述了。
2.2 AnnotationAwareAspectJAutoProxyCreator的作用
我们先来看下该类的类关系图: 咱别的不说,就光看上图中红色框圈起来的地方,看来,AnnotationAwareAspectJAutoProxyCreator 类实现了BeanPostProcessor 接口。也因此,在Spring加载完这个Bean 后,会调用postProcessAfterInitialization 方法,根据类图关系,我们定位到AbstractAutoProxyCreator 类中:
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
@Override
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;
}
}
可见:
- 起因:
AnnotationAwareAspectJAutoProxyCreator 由于实现了BeanPostProcessor 接口无疑会调用postProcessAfterInitialization() 方法。 - 后果:该方法主要负责创建代理对象。经过一系列判断。开始创建代理。
2.3 获取增强器
而上述代码中比较重要的则是第四第五步。我们先来看下第四步,关于增强器(切面)的获取:
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
↓↓↓↓↓
public abstract class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator {
@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();
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
}
2.3.1 获取增强器findCandidateAdvisors
这里我们来看下Spring是如何获取增强器的,从代码出发:
List<Advisor> candidateAdvisors = findCandidateAdvisors();
↓↓↓↓↓↓这里调用的是子类实现,然后再用子类去调用父类↓↓↓↓↓↓
public class AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorAutoProxyCreator {
@Override
protected List<Advisor> findCandidateAdvisors() {
List<Advisor> advisors = super.findCandidateAdvisors();
if (this.aspectJAdvisorsBuilder != null) {
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
}
return advisors;
}
}
我们先来看下第一步findCandidateAdvisors :
public abstract class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator {
protected List<Advisor> findCandidateAdvisors() {
Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available");
return this.advisorRetrievalHelper.findAdvisorBeans();
}
}
↓↓↓↓↓
public class BeanFactoryAdvisorRetrievalHelper {
public List<Advisor> findAdvisorBeans() {
String[] advisorNames = this.cachedAdvisorBeanNames;
if (advisorNames == null) {
advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Advisor.class, true, false);
this.cachedAdvisorBeanNames = advisorNames;
}
if (advisorNames.length == 0) {
return new ArrayList<>();
}
List<Advisor> advisors = new ArrayList<>();
for (String name : advisorNames) {
if (isEligibleBean(name)) {
if (this.beanFactory.isCurrentlyInCreation(name)) {
if (logger.isTraceEnabled()) {
logger.trace("Skipping currently created advisor '" + name + "'");
}
}
else {
try {
advisors.add(this.beanFactory.getBean(name, Advisor.class));
}
catch (BeanCreationException ex) {
}
}
}
}
return advisors;
}
}
再看下第二步buildAspectJAdvisors :
public List<Advisor> buildAspectJAdvisors() {
List<String> aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
synchronized (this) {
aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
List<Advisor> advisors = new ArrayList<>();
aspectNames = new ArrayList<>();
String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Object.class, true, false);
for (String beanName : beanNames) {
if (!isEligibleBean(beanName)) {
continue;
}
Class<?> beanType = this.beanFactory.getType(beanName, false);
if (beanType == null) {
continue;
}
if (this.advisorFactory.isAspect(beanType)) {
aspectNames.add(beanName);
AspectMetadata amd = new AspectMetadata(beanType, beanName);
if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
MetadataAwareAspectInstanceFactory factory =
new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
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 {
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.emptyList();
}
List<Advisor> advisors = new ArrayList<>();
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;
}
上述代码可以总结如下:
- 获取所有的
beanName 。 - 遍历
beanName ,找出声明了AspectJ 注解的类。 - 对标记了
AspectJ 注解的类进行切面的提取。 - 将提取结果加入到缓存中。
那么步骤三也是最为核心的,对应的代码为:
List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
我们来探索下这个方法的具体实现:
public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFactory implements Serializable {
@Override
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
validate(aspectClass);
MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);
List<Advisor> advisors = new ArrayList<>();
for (Method method : getAdvisorMethods(aspectClass)) {
Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, 0, aspectName);
if (advisor != null) {
advisors.add(advisor);
}
}
if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
advisors.add(0, instantiationAdvisor);
}
for (Field field : aspectClass.getDeclaredFields()) {
Advisor advisor = getDeclareParentsAdvisor(field);
if (advisor != null) {
advisors.add(advisor);
}
}
return advisors;
}
}
我们先来重点看下第五步。
(1) 普通增强器的获取
我们来关注下这行代码:
Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, 0, aspectName);
@Override
@Nullable
public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
int declarationOrderInAspect, String aspectName) {
validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());
AspectJExpressionPointcut expressionPointcut = getPointcut(
candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
if (expressionPointcut == null) {
return null;
}
return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
}
再来看下getPointcut 函数做了什么事:
@Nullable
private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) {
AspectJAnnotation<?> aspectJAnnotation =
AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
if (aspectJAnnotation == null) {
return null;
}
AspectJExpressionPointcut ajexp =
new AspectJExpressionPointcut(candidateAspectClass, new String[0], new Class<?>[0]);
ajexp.setExpression(aspectJAnnotation.getPointcutExpression());
if (this.beanFactory != null) {
ajexp.setBeanFactory(this.beanFactory);
}
return ajexp;
}
我们继续探究第一步中findAspectJAnnotationOnMethod 方法的调用流程:
@Nullable
protected static AspectJAnnotation<?> findAspectJAnnotationOnMethod(Method method) {
for (Class<?> clazz : ASPECTJ_ANNOTATION_CLASSES) {
AspectJAnnotation<?> foundAnnotation = findAnnotation(method, (Class<Annotation>) clazz);
if (foundAnnotation != null) {
return foundAnnotation;
}
}
return null;
}
@Nullable
private static <A extends Annotation> AspectJAnnotation<A> findAnnotation(Method method, Class<A> toLookFor) {
A result = AnnotationUtils.findAnnotation(method, toLookFor);
if (result != null) {
return new AspectJAnnotation<>(result);
}
else {
return null;
}
}
到这里,获取切点信息的流程已经讲完,来看下第三步:根据切点信息生成增强器。Spring中,所有的增强都由Advisor 的实现类InstantiationModelAwarePointcutAdvisorImpl 来进行封装,来看下其构造函数:
public InstantiationModelAwarePointcutAdvisorImpl(AspectJExpressionPointcut declaredPointcut,
Method aspectJAdviceMethod, AspectJAdvisorFactory aspectJAdvisorFactory,
MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
this.declaredPointcut = declaredPointcut;
this.declaringClass = aspectJAdviceMethod.getDeclaringClass();
this.methodName = aspectJAdviceMethod.getName();
this.parameterTypes = aspectJAdviceMethod.getParameterTypes();
this.aspectJAdviceMethod = aspectJAdviceMethod;
this.aspectJAdvisorFactory = aspectJAdvisorFactory;
this.aspectInstanceFactory = aspectInstanceFactory;
this.declarationOrder = declarationOrder;
this.aspectName = aspectName;
if (aspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
Pointcut preInstantiationPointcut = Pointcuts.union(
aspectInstanceFactory.getAspectMetadata().getPerClausePointcut(), this.declaredPointcut);
this.pointcut = new PerTargetInstantiationModelPointcut(
this.declaredPointcut, preInstantiationPointcut, aspectInstanceFactory);
this.lazy = true;
}
else {
this.pointcut = this.declaredPointcut;
this.lazy = false;
this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);
}
}
我们重点关注单例增强逻辑,看下instantiateAdvice 函数:
private Advice instantiateAdvice(AspectJExpressionPointcut pointcut) {
Advice advice = this.aspectJAdvisorFactory.getAdvice(this.aspectJAdviceMethod, pointcut,
this.aspectInstanceFactory, this.declarationOrder, this.aspectName);
return (advice != null ? advice : EMPTY_ADVICE);
}
↓↓↓↓getAdvice↓↓↓↓
public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFactory implements Serializable {
@Override
@Nullable
public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,
MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
switch (aspectJAnnotation.getAnnotationType()) {
case AtPointcut:
if (logger.isDebugEnabled()) {
logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
}
return null;
case AtAround:
springAdvice = new AspectJAroundAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtBefore:
springAdvice = new AspectJMethodBeforeAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtAfter:
springAdvice = new AspectJAfterAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtAfterReturning:
springAdvice = new AspectJAfterReturningAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation();
if (StringUtils.hasText(afterReturningAnnotation.returning())) {
springAdvice.setReturningName(afterReturningAnnotation.returning());
}
break;
case AtAfterThrowing:
springAdvice = new AspectJAfterThrowingAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
AfterThrowing afterThrowingAnnotation = (AfterThrowing) aspectJAnnotation.getAnnotation();
if (StringUtils.hasText(afterThrowingAnnotation.throwing())) {
springAdvice.setThrowingName(afterThrowingAnnotation.throwing());
}
break;
default:
throw new UnsupportedOperationException(
"Unsupported advice type on method: " + candidateAdviceMethod);
}
return springAdvice;
}
}
可以看到,Spring根据不同的注解生成对应的增强器。例如AtBefore 则对应AspectJMethodBeforeAdvice 。我们以此为例来分析下该类的实现。
(2) 总结☆
1.调用findCandidateAdvisors() 方法获取所有的候选Class 对象。
- 这里先调用子类
AnnotationAwareAspectJAutoProxyCreator.findCandidateAdvisors() 方法。 - 子类显式地调用了父类
AbstractAdvisorAutoProxyCreator.findCandidateAdvisors() 方法用于加载那行可能通过XML 配置加载的类。 - 只有类上拥有
@Aspect 注解的,才会去寻找增强方法。
2.调用getAdvisors() 方法,获取切面。
- 普通切面的获取(看第三点)。
- 若配置了增强延迟初始化,那么需要在首位加入一个 同步实例化增强器。
- 获取
DeclareParents 注解。
3.循环遍历getAdvisor() 进行切面的获取。
- 校验
- 调用
getPointCut() 方法找到这个 Advisor 里的切点 。 - 根据切点信息生成增强器。
4.getPointCut() 方法做了什么事?
- 利用
AspectJAnnotation 类将获取到的方法上的注解进行封装,支持的注解有:Pointcut, Around, Before, After, AfterReturning, AfterThrowing 。 - 再利用
AspectJExpressionPointcut 对象,将AspectJAnnotation 实例封装起来,同时包含了PointCut 的表达式。例如@Pointcut("execution(* *.test(..))")
5.根据切点信息生成增强器,增强器都由InstantiationModelAwarePointCutAdvisorImpl 来封装。
- 会根据第四步中获取到的具体注解,来生成对应的增强器进行处理。
- 例如
@Before 则对应AspectJMethodBeforeAdvice 。
那么到这里为止,Spring已经完成了所有增强器的解析。即以下问题都在该步骤解决:
- Spring容器中哪些
bean 有@AspectJ 注解? - 而这些
bean 又有哪些具体的增强?是@Around、@Before、@After 的哪一个?
2.3.2 寻找匹配的增强器findAdvisorsThatCanApply
那么接下来就就是需要进行筛选,挑出适合当前bean 的增强器,我们来看下findAdvisorsThatCanApply 方法:
protected List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {
ProxyCreationContext.setCurrentProxiedBeanName(beanName);
try {
return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
}
finally {
ProxyCreationContext.setCurrentProxiedBeanName(null);
}
}
↓↓↓↓↓↓
public abstract class AopUtils {
public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
if (candidateAdvisors.isEmpty()) {
return candidateAdvisors;
}
List<Advisor> eligibleAdvisors = new ArrayList<>();
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) {
continue;
}
if (canApply(candidate, clazz, hasIntroductions)) {
eligibleAdvisors.add(candidate);
}
}
return eligibleAdvisors;
}
}
这里先来讲一下,什么是引介增强?
引介增强是一种特殊的增强,其它的增强是方法级别的增强,即只能在方法前或方法后添加增强。而引介增强则不是添加到方法上的增强, 而是添加到类方法级别的增强,即可以为目标类动态实现某个接口,或者动态添加某些方法。
再看下代码,我们可以发现,无论是特殊的引介增强还是普通的增强,都会调用canApply 函数来匹配bean 和增强之间的关系。我们来看下该函数:
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 {
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) {
return true;
}
IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
}
Set<Class<?>> classes = new LinkedHashSet<>();
if (!Proxy.isProxyClass(targetClass)) {
classes.add(ClassUtils.getUserClass(targetClass));
}
classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
for (Class<?> clazz : classes) {
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;
}
总结下,就是:
- 首先查看定的类是否在
Pointcut 的匹配范围内。 - 是的话,再查看是否能匹配此类任意方法,是的话返回
true 。 - 不能匹配任意方法,便会用反射的方法获取目标类的全部方法进行逐一检测。
2.4 创建代理
上面花了大篇幅所述的内容主要围绕着获取切面的步骤来展开的,那么接下来也就是AOP的最后一步:创建代理了,我们来回顾下外层的调用:
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;
}
紧接着,我们围绕着createProxy 方法来看下Spring做了什么事:
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
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);
}
ClassLoader classLoader = getProxyClassLoader();
if (classLoader instanceof SmartClassLoader && classLoader != beanClass.getClassLoader()) {
classLoader = ((SmartClassLoader) classLoader).getOriginalClassLoader();
}
return proxyFactory.getProxy(classLoader);
}
}
这段代码的主要逻辑也就是:
- 创建代理工厂类,并且复制当前类的属性。
- 封装
Advisor 到工厂中。 - 设置要代理的类。
- 创建代理类。
其中我们来关注下第二步中涉及到的代码。
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
Spring中涉及到许多的拦截器、增强器、增强方法,通过它们来达到对逻辑的增强。因此此时传入的specificInterceptors 对象,可能是上述的任意一种,那么buildAdvisors 函数有必要将其统一进行封装,转化为Advisor 来进行代理的创建。我们来看下其源码:
protected Advisor[] buildAdvisors(@Nullable String beanName, @Nullable Object[] specificInterceptors) {
Advisor[] commonInterceptors = resolveInterceptorNames();
List<Object> allInterceptors = new ArrayList<>();
if (specificInterceptors != null) {
if (specificInterceptors.length > 0) {
allInterceptors.addAll(Arrays.asList(specificInterceptors));
}
}
Advisor[] advisors = new Advisor[allInterceptors.size()];
for (int i = 0; i < allInterceptors.size(); i++) {
advisors[i] = this.advisorAdapterRegistry.wrap(allInterceptors.get(i));
}
return advisors;
}
↓↓↓↓wrap↓↓↓↓
public class DefaultAdvisorAdapterRegistry implements AdvisorAdapterRegistry, Serializable {
@Override
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) {
return new DefaultPointcutAdvisor(advice);
}
for (AdvisorAdapter adapter : this.adapters) {
if (adapter.supportsAdvice(advice)) {
return new DefaultPointcutAdvisor(advice);
}
}
throw new UnknownAdviceTypeException(advice);
}
}
紧接着,Spring将需要进行增强的对象都进行包装完成后,就需要开始创建代理了,我们来看下核心方法:
proxyFactory.getProxy(classLoader);
↓↓↓↓↓↓↓↓↓↓↓↓
public class ProxyFactory extends ProxyCreatorSupport {
public Object getProxy(@Nullable ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader);
}
}
这里我们可以看出有两个步骤:
2.4.1 创建代理createAopProxy
我们来深挖createAopProxy() 方法:
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
return getAopProxyFactory().createAopProxy(this);
}
↓↓↓↓↓↓↓↓
public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (!NativeDetector.inNativeImage() &&
(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() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
}
我们来分类介绍下上述代码中的判断条件。
optimize:用来控制通过Cglib创建的代理是否使用激进的优化策略。
config.isProxyTargetClass()
proxyTargetClass:true时代表目标类本身被代理。而不是目标类的接口。此时创建Cglib代理。
hasNoUserSuppliedProxyInterfaces
代表是否存在代理接口。
(1) JDK和Cglib代理注意事项☆
1.若目标对象实现了接口:
- 默认情况下采用
JDK动态代理 。 - 也可以强制使用
Cglib 代理。
2.若目标对象没有实现接口:
- 必须采用
Cglib 库。Spring自动在JDK 和Cglib 代理之间切换。
3.两者的区别:
JDK动态代理 :只能对实现了接口的类生成代理,不能针对类。Cglib代理 :针对类进行代理。对指定的类生成一个子类,覆盖其中的方法。(注意对应的方法不要声明为final ,否则无法重写)
(2) JDK动态代理案例
1.创建业务接口。
public interface UserService {
abstract void add();
}
2.创建业务接口的实现类。
public class UserServiceImpl implements UserService{
@Override
public void add() {
System.out.println("=============add===============");
}
}
3.创建自定义的InvocationHandler ,用于对接口提供的方法进行增强。
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class MyInvocationHandler implements InvocationHandler {
private Object target;
public MyInvocationHandler(Object target) {
super();
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("==========before===========");
Object res = method.invoke(target, args);
System.out.println("==========after===========");
return res;
}
public Object getProxy() {
return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
target.getClass().getInterfaces(), this);
}
}
4.Test 类。
public class Test {
@org.junit.Test
public void test() {
UserServiceImpl userService = new UserServiceImpl();
MyInvocationHandler handler = new MyInvocationHandler(userService);
UserService proxy = (UserService) handler.getProxy();
proxy.add();
}
}
结果如下:
(2) Cglib代理案例
1.创建拦截器。
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class MethodInterceptorImpl implements MethodInterceptor {
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
System.out.println("Before invoke " + method);
Object res = methodProxy.invokeSuper(obj, args);
System.out.println("After invoke " + method);
return res;
}
}
2.测试类。
public class MyEnhancer {
public static void main(String[] args) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(MyEnhancer.class);
enhancer.setCallback(new MethodInterceptorImpl());
MyEnhancer o = (MyEnhancer) enhancer.create();
o.add();
System.out.println(o);
}
public void add() {
System.out.println("=====add=====");
}
}
结果如下:可见最后生成了个由Cglib 创建的对象实例。
2.4.2 获得代理getProxy
让我们回到源码分析这一块,我们可以看到,Spring中对于AopProxy 接口的getProxy 方法有两种实现:
(1) JDK动态代理原理
同样,我们先看JDK动态代理 方式的getProxy :
final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
}
return Proxy.newProxyInstance(classLoader, this.proxiedInterfaces, this);
}
}
结合上文的JDK动态代理 案例,我们知道其关键是创建自定义的InvocationHandler ,并且实现了自己的getProxy 方法。那么上述源码中,也恰恰是完成了这个操作。而具体的增强逻辑也想必是发生在invoke 函数中。我们来看下JdkDynamicAopProxy.invoke() 函数:
final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {
@Override
@Nullable
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
TargetSource targetSource = this.advised.targetSource;
Object target = null;
try {
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
return equals(args[0]);
}
else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
return hashCode();
}
else if (method.getDeclaringClass() == DecoratingProxy.class) {
return AopProxyUtils.ultimateTargetClass(this.advised);
}
else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
method.getDeclaringClass().isAssignableFrom(Advised.class)) {
return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
}
Object retVal;
if (this.advised.exposeProxy) {
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
target = targetSource.getTarget();
Class<?> targetClass = (target != null ? target.getClass() : null);
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
if (chain.isEmpty()) {
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
}
else {
MethodInvocation invocation =
new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
retVal = invocation.proceed();
}
Class<?> returnType = method.getReturnType();
if (retVal != null && retVal == target &&
returnType != Object.class && returnType.isInstance(proxy) &&
!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
retVal = proxy;
}
else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
throw new AopInvocationException(
"Null return value from advice does not match primitive return type for: " + method);
}
return retVal;
}
finally {
if (target != null && !targetSource.isStatic()) {
targetSource.releaseTarget(target);
}
if (setProxyContext) {
AopContext.setCurrentProxy(oldProxy);
}
}
}
}
这段代码的主要工作就是:
- 创建一个拦截器链,并使用
ReflectiveMethodInvocation 类进行链的封装。 - 调用
ReflectiveMethodInvocation.proceed() 进行拦截器的逐一调用。
我们来看下proceed() 函数:
@Override
@Nullable
public Object proceed() throws Throwable {
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
return dm.interceptor.invoke(this);
}
else {
return proceed();
}
}
else {
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
其主要工作就是:
- 维护调用链中的执行顺序,让其有序执行。
- 而具体的工资则委派给对应的增强器去执行。
(2) Cglib代理原理
形同JDK动态代理 ,我们从getProxy() 函数讲起,这里我们讲另外的一个实现CglibAopProxy.getProxy() :
class CglibAopProxy implements AopProxy, Serializable {
@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 (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 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 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);
}
}
}
上述代码中,主要做这么几件事:
- 目标类和拦截器的获取。
Enhancer 的创建和相关属性设置。- 拦截器的设置。
- 创建代理对象。
其中第三步比较重要,我们来看下拦截器链的设置过程:
Callback[] callbacks = getCallbacks(rootClass);
private Callback[] getCallbacks(Class<?> rootClass) throws Exception {
Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised);
Callback[] mainCallbacks = new Callback[] {
aopInterceptor,
targetInterceptor,
new SerializableNoOp(),
targetDispatcher, this.advisedDispatcher,
new EqualsInterceptor(this.advised),
new HashCodeInterceptor(this.advised)
};
}
不知道各位小伙伴还记得本文的Cglib案例不,里面的代码是这样的:
public static void main(String[] args) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(MyEnhancer.class);
enhancer.setCallback(new MethodInterceptorImpl());
MyEnhancer o = (MyEnhancer) enhancer.create();
o.add();
System.out.println(o);
}
我们可以发现Cglib对于方法的拦截是通过将自定义的拦截器加入到Callback 中并调用代理时,通过激活intercept 方法来实现。
而源码中我们可以发现,Spring将拦截器都加入到了DynamicAdvisedInterceptor 这个类中,而该类又是MethodInterceptor 的实现类。因此具体的Cglib 方式的AOP代理必然在其中实现:
private static class DynamicAdvisedInterceptor implements MethodInterceptor, Serializable {
@Override
@Nullable
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
Object target = null;
TargetSource targetSource = this.advised.getTargetSource();
try {
if (this.advised.exposeProxy) {
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
target = targetSource.getTarget();
Class<?> targetClass = (target != null ? target.getClass() : null);
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
Object retVal;
if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = methodProxy.invoke(target, argsToUse);
}
else {
retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
}
retVal = processReturnType(proxy, target, method, retVal);
return retVal;
}
finally {
if (target != null && !targetSource.isStatic()) {
targetSource.releaseTarget(target);
}
if (setProxyContext) {
AopContext.setCurrentProxy(oldProxy);
}
}
}
}
我们看下第三步,对于拦截器的封装,Cglib 这里使用的是CglibMethodInvocation 类,而JDK动态代理 方式则使用的ReflectiveMethodInvocation 类。
注意:
CglibMethodInvocation 继承了ReflectiveMethodInvocation 类。- 但是并没有重写
proceed 方法,因此后面的逻辑和JDK动态代理 一致。
到这里,创建完代理之后,AOP的实现也就完成了。只要我们自己编码的时候调用相关的方法,就会实现逻辑的增强了。
三. 总结(带流程图)☆
|