1.SpringAOP的基本概念
Aspect切面
就是定义切入点、通知等载体.如果使用@AspectJ注解的方式它就是一个类,如果使用Schema-based(springxml)的方式,它就是一个标签.
例如以@AspectJ注解的方式
@Aspect
public class PointCutExample {
// 定义一个PointCut切点
@Pointcut("execution(* com.spring.Aop..service.*.*(..))")
public void businessService() {}
}
@Aspect
public class AdviceExample {
//定义一个advice通知
@Before("com.spring.Aop.aspect.PointCutExample.businessService()")
public void before(JoinPoint joinPoint) {
log.info("准备执行方法:{},参数列表:{}",joinPoint, Arrays.asList(joinPoint.getArgs()));
}
也可以把通知和切点都写到一个Aspect切面里. 以Schema-based xml的方式
<!--目标对象一个普通bean-->
<bean id="userServiceImpl" class="com.spring.Aop.service.。在上例中目标点就是UserServiceImpl类中的"></bean>
<!--声明一个advice-->
<bean id="logArgsAdvice" class="com.spring.Aop.aspect.LogArgsAdvice"></bean>
<aop:config>
<!--定义切点-->
<aop:pointcut id="logArgsPointCut" expression="execution(* com.spring.Aop..service.*.*(..))"></aop:pointcut>
<!--定义advice通知-->
<aop:aspect ref="logArgsAdvice">
<aop:before method="before" pointcut-ref="logArgsPointCut"></aop:before>
</aop:aspect>
</aop:config>
//advice通知并没有加注解@AspectJ
public class LogArgsAdvice {
public void before(JoinPoint joinPoint) throws Throwable {
log.info("准备执行方法:{},参数列表:{}",joinPoint, Arrays.asList(joinPoint.getArgs()));
}
}
JoinPoint连接点
叫目标点更好理解.就是需要进行拦截的目标方法,在Aop的理念中很多地方都可以作为连接点,进行添加横切逻辑.但springAop中连接点就单指某个方法。在上例中连接目标点就是UserServiceImpl类中的所有方法。
PointCut切点
定义查找匹配连接点的表达式,可以简单的认为PointCut就是JoinPoint的集合. 代表被表达式匹配上的所有连接点.
advice通知
横切逻辑,前置通知、后置通知等等
注意:
@AspectJ注解使用了AOP的概念.跟AspectJ是没有关系的,只是用了个名字。
2.代码实现基于@AspectJ注解方式
定义连接点JoinPoint,也就是需要代理的目标方法 UserService.java
//UserService接口
public interface UserService {
User createUser(String name,Integer age);
User queryUser();
}
//UserServiceImpl实现类
@Slf4j
public class UserServiceImpl implements UserService {
private static User user = null;
@Override
public User createUser(String name, Integer age) {
user = new User();
user.setName(name);
user.setAge(age);
log.info("UserServiceImpl createUser 方法执行中....");
return user;
}
@Override
public User queryUser() {
log.info("UserServiceImpl queryUser 方法执行中....");
return user;
}
}
定义pointCut切点,就是匹配查找JoinPoint连接点的表达式 UserPointCut.java
// 定义PointCut
@Aspect
public class UserPointCut {
@Pointcut("execution(* com.spring.Aop..service.*.*(..))")
public void businessService() {}
}
定义Advice通知,也就是需要增强的横切逻辑
@Slf4j
@Aspect
public class UserAdvice {
@Before("com.spring.Aop.aspect.UserPointCut.businessService()")
public void before(JoinPoint joinPoint) {
log.info("准备执行方法:{},参数列表:{}",joinPoint, Arrays.asList(joinPoint.getArgs()));
}
@AfterReturning(pointcut = "com.spring.Aop.aspect.UserPointCut.businessService()",returning="returnValue")
public void afterReturning(JoinPoint joinPoint,Object returnValue){
log.info("{}方法执行返回:{}",joinPoint,returnValue);
}
application xml配置文件 springAop-2.0aspectJ.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<!--普通bean-->
<bean id="userService" class="com.spring.Aop.service.UserServiceImpl"></bean>
<!--定义advice通知-->
<bean id="userAdvice" class="com.spring.Aop.aspect.UserAdvice"></bean>
<!--开启@AspectJ配置-->
<aop:aspectj-autoproxy/>
</beans>
测试代码
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:springAop-2.0aspectJ.xml");
UserService userService = applicationContext.getBean(UserService.class);
userService.createUser("Jom",12);
userService.queryUser();
运行结果:
3.SpringAop的底层原理
代理模式是springAop的实现原理,但是具体是怎么的呢?如果让我们自己是实现springAop的功能,会怎么做?
3.1动态代理的原理
①.调用Proxy.newProxyInstance生成代理对象.
②.继承InvocationHandler接口,实现Invoke方法,可以在invoke方法添加各种通知横切逻辑,同时调用目标对象的方法.
③.JDK自动生成的代理对象会继承目标对象的接口,并实现目标对象需要代理的方法.方法里再调用②中的invoke方法,而invoke方法中又调用了目标对象的方法,这样就实现了代理的功能.
3.2自己实现aop的思路
①.首先要一个处理aop的工具类
②.找到需要代理的目标类
③.工具类里实现Invoke方法,将寻找到的advice和目标方法调用添加进去.
④.生成代理类对象.因为依赖Jdk动态代理,实现invoke方法将目标对象传入进去即可.
问题:
1.IOC容器如何区分普通类和代理类?--- 通过接口BeanPostProcessor区分的
2.因PointCut切点是匹配表达式,就有可能匹配到很多不同的service方法,会生成一个代理对象包含所有的方法代理?还是生成多个代理对象? ---对于单个被代理的目标对象来说只会生成任意一个代理对象,但在实际执行invoke里会循环执行全部匹配上的advice执行链.
4.源码实现
4.1.查找到处理aop的工具类
在这里是AnnotationAwareAspectJAutoProxyCreator,那怎么找到该类呢?
1.找到开头标签aop对应的命名空间
2.全局搜索命名空间:www.springframework.org/schema/aop 注意http后需加一个 “\”,在spring.handlers找到对应的Handler
3.再根据Handler找到对应的Parser,这里是AspectJAutoProxyBeanDefinitionParser
4.AspectJAutoProxyBeanDefinitionParser代码如下,parse()方法里会注册AnnotationAwareAspectJAutoProxyCreator类.
//解析方法
@Override
@Nullable
public BeanDefinition parse(Element element, ParserContext parserContext) {
//注册类到Ioc容器
AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext, element);
extendBeanDefinition(element, parserContext);
return null;
}
进入registerAspectJAnnotationAutoProxyCreatorIfNecessary方法
public static void registerAspectJAnnotationAutoProxyCreatorIfNecessary(
ParserContext parserContext, Element sourceElement) {
//将一个类定义注册到IOC容器,并返回对象BeanDefinition
//这个就是AnnotationAwareAspectJAutoProxyCreator.class
BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(
parserContext.getRegistry(), parserContext.extractSource(sourceElement));
//处理proxy-target-class与expose-proxy属性,将beanDefinition对应的属性设置为true/false
useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
//注册组件
registerComponentIfNecessary(beanDefinition, parserContext);
}
最终注册bean的key就是这个,下面会进行debug验证.
4.2 Aop处理类Creator何时被加载
那么springIOC容器是知道加载这个类呢?在何时加载的呢?
此处涉及到IOC知识,不详细展开。spring在读取xml配置文件时,会解析xml中的配置,也包括xml文件中的声明部分.
先看下IOC的启动流程,AbstractApplicationContext的refresh()方法.
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
// Prepare this context for refreshing.
prepareRefresh();
// a.此处加载AnnotationAwareAspectJAutoProxyCreator的bean定义
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// b.注册和创建AnnotationAwareAspectJAutoProxyCreator对象
registerBeanPostProcessors(beanFactory);
beanPostProcess.end();
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// c.注册创建普通的bean对象
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
先看a处的代码,进入到obtainFreshBeanFactory()方法,发现里面又调用了refreshBeanFactory()方法. refreshBeanFactory在AbstractRefreshableApplicationContext中代码如下
@Override
protected final void refreshBeanFactory() throws BeansException {
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
//对IOC容器进行定制化,如设置是否允许循环引用、是否允许bean定义覆盖重写等
customizeBeanFactory(beanFactory);
//加载Bean定义
loadBeanDefinitions(beanFactory);
this.beanFactory = beanFactory;
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
loadBeanDefinitions方法最终会调用执行上面的AspectJAutoProxyBeanDefinitionParser的parse方法.loadBeanDefinitions执行后debug如下
可以看到BeanDefinitionMap里除了我们自己定义的bean之外,还多了一个org.springframework.aop.config.internalAutoProxyCreator。
4.2.创建Aop处理类Creator的对象
先看看Creator类的继承关系图如下
可以看到该类继承实现了BeanPostProcessor接口.这个接口大家应该很熟悉,就是spring设计的扩展功能实现.
另外关于动态代理的执行时机问题,是需要目标对象被创建初始化后,才能进行动态处理操作.不然目标对象都没有,代理谁呢?不符合逻辑.
从IOC的启动流程来说,有了Bean定义同时又实现了BeanPostProcessor接口.故在registerBeanPostProcessors(beanFactory)时会将该Creator类注册到容器里,参看4.2 b处的代码.注意这里注册就会创建Creator类对象了,创建的时机在普通的bean之前,这点尤其重要.
registerBeanPostProcessors源码如下:
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
//查找实现了BeanPostProcessor的类
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
// Separate between BeanPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
// 存放实现PriorityOrdered的PostProcessors
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
// 存放实现MergedBeanDefinitionPostProcessor的PostProcessors
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
// 存放实现Ordered的PostProcessors
List<String> orderedPostProcessorNames = new ArrayList<>();
// 存放以外情况的PostProcessors
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
// 此时PostProcessors对象还没有被创建,所以存放beanName
priorityOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// First, register the BeanPostProcessors that implement PriorityOrdered.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// Next, register the BeanPostProcessors that implement Ordered.
// 这里注册实现了Ordered的BeanPostProcessors
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String ppName : orderedPostProcessorNames) {
// 重点:创建BeanPostProcessors对象 最终会调用执行doCreateBean方法.
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
sortPostProcessors(orderedPostProcessors, beanFactory);
//将创建好的BeanPostProcessors对象 存放到beanPostProcessors列表中.
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
// Now, register all regular BeanPostProcessors.
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
// Finally, re-register all internal BeanPostProcessors.
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
// Re-register post-processor for detecting inner beans as ApplicationListeners,
// moving it to the end of the processor chain (for picking up proxies etc).
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
到这里AnnotationAwareAspectJAutoProxyCreator类的对象已经创建好了,提前创建此种类型对象spring是通过其继承实现了BeanPostProcessor识别的.
4.4 创建普通Bean对象,如何变成代理对象的
创建普通Bean对象也就是需要代理的目标对象,在refresh()方法的finishBeanFactoryInitialization(beanFactory)里面,参看4.2的c处标记。 通过该方法一直点下去,最终会调用到AbstractAutowireCapableBeanFactory.doCreateBean()真正创建对象的地方.如下
//省略。。。。
if (instanceWrapper == null) {
// 创建对象
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
//省略。。。。
// Initialize the bean instance.
Object exposedObject = bean;
try {
// 填充Bean,设置属性啥的
populateBean(beanName, mbd, instanceWrapper);
// 初始化Bean
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
//省略。。。。
进入initializeBean方法
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
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()) {
// 1. 执行每一个 BeanPostProcessor 的 postProcessBeforeInitialization 方法
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// 调用 bean 配置中的 init-method="xxx"
invokeInitMethods(beanName, wrappedBean, mbd);
}
....
if (mbd == null || !mbd.isSynthetic()) {
// 2.重点关注 执行每一个 BeanPostProcessor 的 postProcessAfterInitialization方法
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
applyBeanPostProcessorsAfterInitialization会循环调用IOC容器中所有的BeanPostProcessor,上面创建的Creator对象的postProcessAfterInitialization在这里会被执行,执行后目标对象就被包装成代理对象了。 至此IOC是如何加载代理对象和普通目标对象就清晰了。接下来就是SpringAop主要内容了。
4.5 创建代理对象
被调用的postProcessAfterInitialization方法在AnnotationAwareAspectJAutoProxyCreator的父接口AbstractAutoProxyCreator中,如下
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
//此处的参数bean和beanName就是目标对象,此时目标对象已经被创建出来了.
if (bean != null) {
//从缓存中获取bean的名字key,如果是FactoryBean类型的key前面加&标识,以外的正常返回
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
//执行处理,处理完如果是aop类型就返回代理后的对象,给到ioc容器
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
wrapIfNecessary方法的详细处理
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
//beanName不可空 && 已经处理过的直接返回
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
//advisedBeans中包含是类型为Advice、Pointcut、Advisor、AopInfrastructureBean都跳过直接返回.
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;
}
// 4.5.1 寻找匹配该目标Bean的横切逻辑方法(advice和advisor之类的)
// 在我们上面的例子就是UserAdvice里的before和afterReturning方法
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
//4.5.2生成真正的代理对象proxy,即利用JDK动态代理或cglib生成的$proxy0@xxx对象
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;
}
这步处理结束后、就返回想要的代理对象了.
4.5.1 寻找匹配目标Bean的通知方法(advice和advisor)
getAdvicesAndAdvisorsForBean是抽象方法,具体的实现有2个子类分别是AbstractAdvisorAutoProxyCreator和BeanNameAutoProxyCreator。 而AbstractAdvisorAutoProxyCreator是上面注册的AnnotationAwareAspectJAutoProxyCreator的父类,故找AbstractAdvisorAutoProxyCreator中相应的方法.
@Nullable
protected abstract Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName,
@Nullable TargetSource customTargetSource) throws BeansException;
AbstractAdvisorAutoProxyCreator中getAdvicesAndAdvisorsForBean()
protected Object[] getAdvicesAndAdvisorsForBean(
Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
//查找合适的advisor(继承和注解advisor的类)
List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
if (advisors.isEmpty()) {
return DO_NOT_PROXY;
}
return advisors.toArray();
}
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
//先找到容器中全部的advisor
List<Advisor> candidateAdvisors = findCandidateAdvisors();
//再匹配beanName对应的advisor
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
4.5.1.1 查找全部的advisor
findCandidateAdvisors()方法,上面的处理是在AbstractAdvisorAutoProxyCreator中,而findCandidateAdvisors方法在其类中有实现,且在子类中也有实现,此处应该去AnnotationAwareAspectJAutoProxyCreator中的实现,优先调用自己的方法
protected List<Advisor> findCandidateAdvisors() {
// 找到所有继承了Advisor.class的子类
List<Advisor> advisors = super.findCandidateAdvisors();
// Build Advisors for all AspectJ aspects in the bean factory.
if (this.aspectJAdvisorsBuilder != null) {
//寻找注解的advisor
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
}
return advisors;
}
经过处理后的advisors里面封装了pointCut和advice信息
4.5.1.2 匹配目标beanName对应的advisor
findAdvisorsThatCanApply()方法
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) {
// already processed
continue;
}
if (canApply(candidate, clazz, hasIntroductions)) {
eligibleAdvisors.add(candidate);
}
}
return eligibleAdvisors;
}
4.5.2 生成具体的代理对象
org.springframework.aop.framework.autoproxy.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();
proxyFactory.copyFrom(this);
// 判断proxy-target-class="true"
if (proxyFactory.isProxyTargetClass()) {
if (Proxy.isProxyClass(beanClass)) {
for (Class<?> ifc : beanClass.getInterfaces()) {
proxyFactory.addInterface(ifc);
}
}
}
else {
// No proxyTargetClass flag enforced, let's apply our default checks...
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);
}
// Use original ClassLoader if bean class not locally loaded in overriding class loader
ClassLoader classLoader = getProxyClassLoader();
if (classLoader instanceof SmartClassLoader && classLoader != beanClass.getClassLoader()) {
classLoader = ((SmartClassLoader) classLoader).getOriginalClassLoader();
}
return proxyFactory.getProxy(classLoader);
}
可以看到proxyFactory对象封装了advisors和目标对象的信息. proxyFactory.getProxy()
public Object getProxy(@Nullable ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader);
}
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
return getAopProxyFactory().createAopProxy(this);
}
根据配置先创建AopProxy对象,再根据AopProxy创建具体的proxy对象.是用JDK动态代理还是Cglib方式. DefaultAopProxyFactory类createAopProxy()
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
//此处的config参数就是proxyFactory对象
if (!NativeDetector.inNativeImage() &&
(config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config))) {
Class<?> targetClass = config.getTargetClass();
...
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
我们只看JdkDynamicAopProxy方法在JdkDynamicAopProxy类中
public JdkDynamicAopProxy(AdvisedSupport config) throws AopConfigException {
//如果不存在Advisor或者目标对象为空的话 抛出异常
if (config.getAdvisorCount() == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) {
throw new AopConfigException("No advisors and no TargetSource specified");
}
this.advised = config;
//获取advised里代理对象所继承的所有接口
this.proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
//判断标记继承的接口是否有实现equals和hashCode方法
findDefinedEqualsAndHashCodeMethods(this.proxiedInterfaces);
}
创建具体的代理对象
@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);
}
至此代理对象就创建完成了.
4.6 执行调用Aop对象
此处只看JdkDynamicAopProxy JDK动态代理的方式 JDK动态代理的原理,生成的代理对象的方法内部会委托给InvocationHandler.invoke()方法。而invoke方法就会包含各个增强方法(通知),再调用原对象的方法。 看一下JdkDynamicAopProxy的源码实现了InvocationHandler接口
final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {
重点invoke()
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)) {
// The target does not implement the equals(Object) method itself.
return equals(args[0]);
}
else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
// The target does not implement the hashCode() method itself.
return hashCode();
}
//method.getDeclaringClass获取Method对应的目标类,method.getClass获得是Method类
else if (method.getDeclaringClass() == DecoratingProxy.class) {
// There is only getDecoratedClass() declared -> dispatch to proxy config.
return AopProxyUtils.ultimateTargetClass(this.advised);
}
//Advised接口或者其父接口中定义的方法,直接反射调用,不应用通知
else 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;
if (this.advised.exposeProxy) {
// Make invocation available if necessary.
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
//获取目标对象的类
target = targetSource.getTarget();
Class<?> targetClass = (target != null ? target.getClass() : null);
// 获取目标方法的拦截器链.程序上我们可以定义多个Aop切面,而某个目标方法就有可能被多个Aop匹配上,故需要循环执行每个匹配的aop通知.
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
MethodInvocation invocation =
new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
// Proceed to the joinpoint through the interceptor 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()) {
// Must have come from TargetSource.
targetSource.releaseTarget(target);
}
if (setProxyContext) {
// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);
}
}
}
ReflectiveMethodInvocation的proceed()
public Object proceed() throws Throwable {
// 如果执行Interceptor完了,则执行joinPoint.注意currentInterceptorIndex初始值为-1
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
// 执行Interceptor,根据currentInterceptorIndex逐个获取Interceptor
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
//是否需要动态匹配
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
// Evaluate dynamic method matcher here: static part will already have
// been evaluated and found to match.
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 {
// Dynamic matching failed.
// Skip this interceptor and invoke the next in the chain.
return proceed();
}
}
else {
// It's an interceptor, so we just invoke it: The pointcut will have
// been evaluated statically before this object was constructed.
//执行当前IntercetporAdvice的invoke方法
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
为什么@Before、@After的Advice的invoke可以实现前置、后置的通知效果? MethodBeforeAdviceInterceptor的invoke()
public Object invoke(MethodInvocation mi) throws Throwable {
//先执行before方法,执行完后再回调ReflectiveMethodInvocation.proceed()
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
return mi.proceed();
}
AfterReturningAdviceInterceptor的invoke()
public Object invoke(MethodInvocation mi) throws Throwable {
//先回调ReflectiveMethodInvocation.proceed(),因为调用joinPoint在这里
Object retVal = mi.proceed();
//再执行afterReturning
this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
return retVal;
}
结束。
5.总结
Aop首先需要理解基础的概念,有哪些具体是什么用处,怎么使用的。
其次理解动态代理的原理,这是理解aop的基础。
最后具体的aop实现步骤,先创建代理对象 -> 创建目标对象时 -> 判断是否有匹配上的代理对象 ->找到所有的advice和pointCut -> 再找到和目标对象匹配的advice和pointCut -> 生成实际的代理对象 -> 程序调用 -> 代理对象里会调用invoke方法 -> 执行具体的横切逻辑通知 -> 执行调用目标对象.
另仅个人学习记录,有理解不到位的情况...