前面的函数中已经完成了所有增强器的解析,但是对于所有增强器来讲,并不一定都适用于当前的Bean,还要挑取除适合的增强器,也就是满足我们配置的通配符的增强器。具体的实现在findAdvisorsThatCanApply中。
public static List findAdvisorsThatCanApply(List candidateAdvisors, Class clazz)
{
if(candidateAdvisors.isEmpty())
return candidateAdvisors;
List eligibleAdvisors = new LinkedList();
//首先处理引介增强
for(Advisor candidate:candidateAdvisors)
if((candidate instanceof IntroductionAdvisor) && canApply(candidate, clazz))
eligibleAdvisors.add(candidate);
boolean hasIntroductions = !eligibleAdvisors.isEmpty();
for(Advisor candidate : candidateAdvisors){
//对于普通bean的处理
if(!(candidate instanceof IntroductionAdvisor) && canApply(candidate, clazz, hasIntroductions))
eligibleAdvisors.add(candidate);
return eligibleAdvisors;
}
findAdvisorsThatCanApply函数的主要功能是寻找所有增强器中适用于当前class的增强器。对于真是的匹配在canApply中实现。
public static boolean canApply(Advisor advisor, Class targetClass, boolean hasIntroductions)
{
if(advisor instanceof IntroductionAdvisor)
return ((IntroductionAdvisor)advisor).getClassFilter().matches(targetClass);
if(advisor instanceof PointcutAdvisor)
{
PointcutAdvisor pca = (PointcutAdvisor)advisor;
return canApply(pca.getPointcut(), targetClass, hasIntroductions);
} else
{
//It dosen't have a pointcut so we assume it applies.
return true;
}
}
hodMatcher introductionAwareMethodMatcher = null;
if(methodMatcher instanceof IntroductionAwareMethodMatcher)
introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher)methodMatcher;
Set classes = new HashSet(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
classes.add(targetClass);
for(Iterator i$ = classes.iterator(); i$.hasNext();)
{
Class clazz = (Class)i$.next();
Method methods[] = clazz.getMethods();
Method arr$[] = methods;
int len$ = arr$.length;
int i$ = 0;
while(i$ < len$)
{
Method method = arr$[i$];
if(introductionAwareMethodMatcher != null && introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) || methodMatcher.matches(method, targetClass))
return true;
i$++;
}
}
return false;
}
3,创建代理
在获取了所有对应bean的增强后,便可以进行代理的创建了。
protected Object createProxy(Class beanClass, String beanName, Object specificInterceptors[], TargetSource targetSource)
{
ProxyFactory proxyFactory = new ProxyFactory();
//获取当前类中相关属性
proxyFactory.copyFrom(this);
//检查proxyTargeClass设置以及preserveTargetClass属性
<pre name="code" class="java"> //决定对于给定的bean是否应该使用targetClass而不是他的接口代理
if(!shouldProxyTargetClass(beanClass, beanName)) { //Must allow forintroductions;cant just set interfaces to the targets interfaces only.
Class targetInterfaces[] = ClassUtils.getAllInterfacesForClass(beanClass, proxyClassLoader); for(Class<?> targetInterface : targetInterfaces) { //添加代理接口 proxyFactory.addInterface(targetInterface); } } Advisor advisors[] = buildAdvisors(beanName, specificInterceptors); for(Advisor advisor : advisors) { //加入增强器 proxyFactory.addAdvisor(advisor); } //设置要代理的类 proxyFactory.setTargetSource(targetSource); //定制代理
customizeProxyFactory(proxyFactory); //缺省值为false即izai代理被配置之后,不允许修改代理的配置。
proxyFactory.setFrozen(freezeProxy); if(advisorsPreFiltered()) proxyFactory.setPreFiltered(true); return proxyFactory.getProxy(proxyClassLoader); } 其中,封装Advisor并加入到ProxyFactory中以及创建代理是两个相对繁琐的过程,可以通过ProxyFactory提供的addAdvisor方法直接将增强器置入代理创建工厂中,但是将拦截器封装为增强器还是需要一定的逻辑的。
protected Advisor[] buildAdvisors(String beanName, Object specificInterceptors[])
{
//解析注册的所有interceptorName
Advisor commonInterceptors[] = resolveInterceptorNames();
List allInterceptors = new ArrayList();
if(specificInterceptors != null)
{
//加入拦截器
allInterceptors.addAll(Arrays.asList(specificInterceptors));
if(commonInterceptors != null)
if(applyCommonInterceptorsFirst)
allInterceptors.addAll(0, Arrays.asList(commonInterceptors));
else
allInterceptors.addAll(Arrays.asList(commonInterceptors));
}
if(logger.isDebugEnabled())
{
int nrOfCommonInterceptors = commonInterceptors == null ? 0 : commonInterceptors.length;
int nrOfSpecificInterceptors = specificInterceptors == null ? 0 : specificInterceptors.length;
logger.debug((new StringBuilder()).append("Creating implicit proxy for bean '").append(beanName).append("' with ").append(nrOfCommonInterceptors).append(" common interceptors and ").append(nrOfSpecificInterceptors).append(" specific interceptors").toString());
}
Advisor advisors[] = new Advisor[allInterceptors.size()];
for(int i = 0; i < allInterceptors.size(); i++)
//拦截器进行封装转化为Advisor
advisors[i] = advisorAdapterRegistry.wrap(allInterceptors.get(i));
return advisors;
}
public Advisor wrap(Object adviceObject)
throws UnknownAdviceTypeException
{
//如果要封装的对象本身就是Advisor类型的那么无需坐过多处理
if(adviceObject instanceof Advisor)
return (Advisor)adviceObject;
//因为此封装只对Advisor和Advice两种类型的数据有效,如果不是将不能封装
if(!(adviceObject instanceof Advice))
throw new UnknownAdviceTypeException(adviceObject);
Advice advice = (Advice)adviceObject;
if(advice instanceof MethodInterceptor)
//如果是MethodInterceptor类型则使用DefaultPointcutrAdvisor封装
return new DefaultPointcutAdvisor(advice);
//如果存在Advisor类型的适配器那么也同样需要进行封装
for(Iterator i$ = adapters.iterator(); i$.hasNext();)
{
AdvisorAdapter adapter = (AdvisorAdapter)i$.next();
if(adapter.supportsAdvice(advice))
return new DefaultPointcutAdvisor(advice);
}
throw new UnknownAdviceTypeException(advice);
}
由于Spring中涉及过多的拦截器,增强器,增强方法等方式来对逻辑进行增强,所以非常有必要统一封装成Advisor来进行代理的创建,完成了增强的封装过程,那么解析最终的一部就是代理的创建驭获取了。
public Object getProxy(ClassLoader classLoader)
{
return createAopProxy().getProxy(classLoader);
}
1创建代理
protected final synchronized AopProxy createAopProxy()
{
if(!active)
activate();
//创建代理
return getAopProxyFactory().createAopProxy(this);
}
<pre name="code" class="java"> 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);
else
return CglibProxyFactory.createCglibProxy(config);
} else
{
return new JdkDynamicAopProxy(config);
}
}
到此已经完成了代理的创建,不管我们之前是否有阅读过Spring的源码,但是都或多或少地听过对于Spirng的代理中JDKProxy的实现和CglibProxy的实现。Spring是如何选取的呢?网上的介绍到处都是,现在我们就从源代码的角度分析,看看到底Spring是如何选择代理方式的。
从if中的判断条件可以看到3个方面影响着Spring的判断
- optimize:用来控制通过CGLIB创建的代理是否使用激进的优化策略。除非完全了解AOP代理是如何优化,否则不推荐用户使用这个设置,目前这个属性仅用于CGLIB代理,对于JDK动态代理(缺省代理)无效。
- proxyTargetClass:这个属性为treu时,目标类本身被代理而不是目标类的接口。如果这个属性值被设为true,CGLIB代理将被创建,。
- hasNOUser Supplied Proxy Interfaces:是否存在代理接口。、