1. 测试方法
通知类:
public class LogMethodBeforeAdvice implements MethodBeforeAdvice {
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println("this is logMethodBeforeAdvice!");
}
}
public class Log2MethodBeforeAdvice implements MethodBeforeAdvice {
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println("xxxxxxxxxxxxxxxxx");
}
}
目标接口以及目标类:
public interface IAccount {
String say(@NotNull Integer id, @NotNull String desc);
String run();
//接口内部定义了hashCode方法
int hashCode();
}
public class AccountImpl implements IAccount {
@Override
public String say(@NotNull Integer id, @NotNull String desc) {
return "my "+id + ":" + desc;
}
@Override
public String run() {
return "I am runner";
}
//继承的是IAccount的hashCode方法
@Override
public int hashCode() {
return 123;
}
//继承的是Object的equals方法
@Override
public boolean equals(Object obj) {
return super.equals(obj);
}
}
测试方法:
@Configuration
public class DefaultAdvisorAutoProxyCreatorConfig {
//目标类
@Bean
public IAccount accountImpl(){
return new AccountImpl();
}
//切面类
@Bean
public Log2MethodBeforeAdvice log2(){
return new Log2MethodBeforeAdvice();
}
//声明自动代理器
@Bean
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
return new DefaultAdvisorAutoProxyCreator();
}
//声明Advisor
@Bean
public NameMatchMethodPointcutAdvisor nameMatchMethodPointcutAdvisor() {
NameMatchMethodPointcutAdvisor nameAdvisor = new NameMatchMethodPointcutAdvisor();
//拦截方法
nameAdvisor.addMethodName("*say");
nameAdvisor.setAdvice(new LogMethodBeforeAdvice());
return nameAdvisor;
}
}
2. 类结构
DefaultAdvisorAutoProxyCreator
是AbstractAdvisorAutoProxyCreator
的子类,由下面方法可知,实现了isEligibleAdvisorBean
方法。
AbstractAdvisorAutoProxyCreator
类是AbstractAutoProxyCreator
的子类,由下面方法可知,实现了getAdvicesAndAdvisorsForBean()
和advisorsPreFiltered()
方法。
- getAdvicesAndAdvisorsForBean()方法:获取该bean对象上所有的Advisor对象(实现自动代理的核心方法);
-
advisorsPreFiltered():默认返回
true
,是着ProxyFactory
代理配置;
AbstractAutoProxyCreator
是模板类,即Spring
完成自动代理的模板方法,定义了算法骨干。子类实现其定义的钩子方法,完成bean
的自动代理。
3. 源码分析
3.1 Spring的自动加载流程
调用如下方法:getBean()
获取单例池中的bean对象。而bean被初始化时,就会被自动
代理。
public class TestSpringProxy {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(DefaultAdvisorAutoProxyCreatorConfig.class);
//可以使用@Primary指定元素,或直接使用name名获取。
IAccount bean = (IAccount)applicationContext.getBean("accountImpl");
bean.say(100,"工作");
System.out.println(bean.getClass());
}
}
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
//前置处理,未进行代理
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
return bean;
}
}
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
//获取cacheKey的(对FactoryBean进行处理,加入了&)
Object cacheKey = getCacheKey(bean.getClass(), beanName);
//判断是否被循环依赖时早期加载
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
//包装Bean对象(自动代理)
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
}
3.2 创建代理对象
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
private final Set<String> targetSourcedBeans = Collections.newSetFromMap(new ConcurrentHashMap<>(16));
private final Map<Object, Boolean> advisedBeans = new ConcurrentHashMap<>(256);
//包装bean对象
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
//若bean已经在targetSourcedBeans集合中,说明已经被代理过,直接返回即可。
//`postProcessBeforeInstantiation()`中成功创建的代理对象会将beanName加入到`targetSourceBeans`中。
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
//若该Bean是基础框架或者免代理的Bean,也不进行处理。
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
//若`Pointcut`、`Advice`、`Advisor`、`AopInfrastructureBean`也不会进行代理,并且加入到advisedBeans集合中。
//或者判断是否跳过(shouldSkip也是一个钩子方法)
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// (重要方法)获取bean上的advice和advisor对象。(该方法是`AbstractAdvisorAutoProxyCreato`内的方法)。获取合格的Advisor
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
}
AbstractAutoProxyCreator#shouldSkip
的方法,也是一个钩子方法。AspectJAwareAdvisorAutoProxyCreator
(子类)实现了shouldSkip
方法。
父类中shouldSkip
方法作用是判断该bean是否是beanName.ORIGINAL
的类型,若bean是这种类型,则跳过。
public abstract class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator {
@Nullable
private BeanFactoryAdvisorRetrievalHelper advisorRetrievalHelper;
@Override
@Nullable
protected Object[] getAdvicesAndAdvisorsForBean(
Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
//获取`合格`的Advisor集合。
List<Advisor> 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();
//筛选候选的Advisor对象,获取`合格的Advisor`对象集合;
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
//子类实现(扩展Advisors)
extendAdvisors(eligibleAdvisors);
//Advisor按照Order接口进行排序。
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
//返回该bean上的Advicor对象
return eligibleAdvisors;
}
//获取`所有候选的Advisor集合`(钩子方法,子类也会实现)
protected List<Advisor> findCandidateAdvisors() {
Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available");
return this.advisorRetrievalHelper.findAdvisorBeans();
}
//获取`合格的Advisor`集合
protected List<Advisor> findAdvisorsThatCanApply(
List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {
ProxyCreationContext.setCurrentProxiedBeanName(beanName);
try {
return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
}
finally {
ProxyCreationContext.setCurrentProxiedBeanName(null);
}
}
//钩子方法,未实现。
protected void extendAdvisors(List<Advisor> candidateAdvisors) {
}
//适配器模式(主要为了实现isEligibleAdvisorBean方法)
private class BeanFactoryAdvisorRetrievalHelperAdapter extends BeanFactoryAdvisorRetrievalHelper {
public BeanFactoryAdvisorRetrievalHelperAdapter(ConfigurableListableBeanFactory beanFactory) {
super(beanFactory);
}
//获取合格的Bean的对象。
@Override
protected boolean isEligibleBean(String beanName) {
return AbstractAdvisorAutoProxyCreator.this.isEligibleAdvisorBean(beanName);
}
}
}
public class BeanFactoryAdvisorRetrievalHelper {
//维护的Advisor缓存(初始时为null)
@Nullable
private volatile String[] cachedAdvisorBeanNames;
public List<Advisor> findAdvisorBeans() {
String[] advisorNames = this.cachedAdvisorBeanNames;
//初始化时为null
if (advisorNames == null) {
//从容器中(包含父容器)中获取Advisor类型的Bean对象的名字。【注意是Advisor类型,而非Advice类型】
advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Advisor.class, true, false);
//放入本地缓存中。
this.cachedAdvisorBeanNames = advisorNames;
}
if (advisorNames.length == 0) {
return new ArrayList<>();
}
List<Advisor> advisors = new ArrayList<>();
//获取Spring容器中所有的advisors后开始处理。
for (String name : advisorNames) {
//判断该Advisor是否是可以自动代理的Advisor(由子类实现判断)
if (isEligibleBean(name)) {
//若bean正在创建,那么什么都不做。
if (this.beanFactory.isCurrentlyInCreation(name)) {
if (logger.isTraceEnabled()) {
logger.trace("Skipping currently created advisor '" + name + "'");
}
}
//bean已经被创建后
else {
try {
//创建Bean,放入List<Advisor>中。
advisors.add(this.beanFactory.getBean(name, Advisor.class));
}
catch (BeanCreationException ex) {
...
continue;
}
throw ex;
}
}
}
}
return advisors;
}
//钩子方法(由具体子类实现)
protected boolean isEligibleBean(String beanName) {
return true;
}
}
子类的特殊实现:
public class DefaultAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator implements BeanNameAware {
private boolean usePrefix = false;
@Nullable
private String advisorBeanNamePrefix;
@Override
protected boolean isEligibleAdvisorBean(String beanName) {
//usePrefix boolean类型,默认false
if (!isUsePrefix()) {
return true;
}
String prefix = getAdvisorBeanNamePrefix();
return (prefix != null && beanName.startsWith(prefix));
}
}
public abstract class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator {
//遭到Bean上合格的Advisor
protected List<Advisor> findAdvisorsThatCanApply(
List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {
//将beanName放入到`currentProxiedBeanName`中,以便可以在ThreadLocal中获取。
ProxyCreationContext.setCurrentProxiedBeanName(beanName);
try {
//candidateAdvisors:Spring容器中所有的advisor对象;
//beanClass:Bean对象类型;
return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
}
finally {
ProxyCreationContext.setCurrentProxiedBeanName(null);
}
}
}
AopUtils的工具方法:
public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
//若是传入的容器内Advisor为空,直接返回
if (candidateAdvisors.isEmpty()) {
return candidateAdvisors;
}
List<Advisor> eligibleAdvisors = new ArrayList<>();
//bean匹配`引介通知`。
for (Advisor candidate : candidateAdvisors) {
//判断是否是引介通知(引介通知只有ClassFilter),且匹配
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;
}
public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
if (advisor instanceof IntroductionAdvisor) {
return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);
}
else if (advisor instanceof PointcutAdvisor) {
PointcutAdvisor pca = (PointcutAdvisor) advisor;
return canApply(pca.getPointcut(), targetClass, hasIntroductions);
}
else {
// It doesn't have a pointcut so we assume it applies.
return true;
}
}
public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
Assert.notNull(pc, "Pointcut must not be null");
//切点的classFilter是否匹配
if (!pc.getClassFilter().matches(targetClass)) {
return false;
}
//获取切点的methodMatcher
MethodMatcher methodMatcher = pc.getMethodMatcher();
//若是方法匹配的值为MethodMatcher.TRUE,则拦截所有的方法
if (methodMatcher == MethodMatcher.TRUE) {
return true;
}
IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
}
Set<Class<?>> classes = new LinkedHashSet<>();
//若不是JDK代理
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) {
//所有的方法进行匹配(包含私有方法),若有一个匹配,那么返回true。
if (introductionAwareMethodMatcher != null ?
introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :
methodMatcher.matches(method, targetClass)) {
return true;
}
}
}
return false;
}
创建代理对象
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
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;
}
//此时我们在这(获取到该Bean上的所有Advisor对象)
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
//将该Bean放入到advisedBeans集合中。
this.advisedBeans.put(cacheKey, Boolean.TRUE);
//在SingletonTargetSource获取targetSource。
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;
}
//创建代理对象
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获取Proxy对象。
ProxyFactory proxyFactory = new ProxyFactory();
//复制ProxyConfig配置属性。
proxyFactory.copyFrom(this);
//若proxyTargetClass=false,则为JDK代理;
//若proxyTargetClass=true,则为CGLIB代理
if (!proxyFactory.isProxyTargetClass()) {
//判断是否应该使用targetClass类而不是接口进行代理。
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
//把这个类实现的接口们,放入到ProxyFactory中。
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
//处理Advisor对象
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);
//子类定制proxyFactory对象
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
// 注意此处。
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
//创建代理对象。
return proxyFactory.getProxy(getProxyClassLoader());
}
//specificInterceptors:该Bean上所有的Advisor。
protected Advisor[] buildAdvisors(@Nullable String beanName, @Nullable Object[] specificInterceptors) {
Advisor[] commonInterceptors = resolveInterceptorNames();
List<Object> allInterceptors = new ArrayList<>();
if (specificInterceptors != null) {
allInterceptors.addAll(Arrays.asList(specificInterceptors));
if (commonInterceptors.length > 0) {
//绝对拦截器加入的顺序
if (this.applyCommonInterceptorsFirst) {
allInterceptors.addAll(0, Arrays.asList(commonInterceptors));
}
else {
allInterceptors.addAll(Arrays.asList(commonInterceptors));
}
}
}
Advisor[] advisors = new Advisor[allInterceptors.size()];
for (int i = 0; i < allInterceptors.size(); i++) {
advisors[i] = this.advisorAdapterRegistry.wrap(allInterceptors.get(i));
}
return advisors;
}
//处理拦截器Name,去容器内找出来
private Advisor[] resolveInterceptorNames() {
BeanFactory bf = this.beanFactory;
ConfigurableBeanFactory cbf = (bf instanceof ConfigurableBeanFactory ? (ConfigurableBeanFactory) bf : null);
List<Advisor> advisors = new ArrayList<>();
for (String beanName : this.interceptorNames) {
//若工厂不是ConfigurableBeanFactory 或者该Bean不在创建中
if (cbf == null || !cbf.isCurrentlyInCreation(beanName)) {
Assert.state(bf != null, "BeanFactory required for resolving interceptor names");
//拿到这个Bean,将其包装为Advisor。
Object next = bf.getBean(beanName);
advisors.add(this.advisorAdapterRegistry.wrap(next));
}
}
return advisors.toArray(new Advisor[0]);
}
}
上述的buildAdvisors()
方法中存在resolveInterceptorNames()
方法,实际上是处理数组interceptorNames
中的beanName,将其在Spring单例池中获取到,并且加入到advisors
中。
当然需要依赖applyCommonInterceptorsFirst
参数的值来决定拦截器的顺序。
需要注意的是:是否创建代理对象由pointcut
来决定。而创建出代理对象执行方法时,该方法会选择合适和Advisor
进行织入。而Bean会保存所有相关的Advisor
。
执行代理方法
为每个方法生成过滤链:依旧依赖的是pointcut
的ClassFilter
和MethodMatcher
对Advice的过滤。
依赖的是NameMatchMethodPointcut
对名字的过滤:
public class NameMatchMethodPointcut extends StaticMethodMatcherPointcut implements Serializable {
private List<String> mappedNames = new ArrayList<>();
@Override
public boolean matches(Method method, Class<?> targetClass) {
//mappedNames为传入的名字匹配模式
for (String mappedName : this.mappedNames) {
//判断是否匹配
if (mappedName.equals(method.getName()) || isMatch(method.getName(), mappedName)) {
return true;
}
}
return false;
}
}
若是符合条件,那么该方法上会生成过滤器链。
- 创建代理流程:找到该Bean对象上所有的Advisor时,使用了Advisor中Pointcut的
类过滤
和方法过滤
。 - 使用代理对象:需要为每个方法创建
AdvisorChain
,而Bean
对象已经在创建代理流程
中使用了类过滤
,那么创建AdvisorChain
无需在进行类过滤
。
如上图所示,该属性使用的场景均是获取方法的AdvisorChain时
进行ClassFilter
过滤的场景。