文章目录
前提:实现代理之前,已经拿到类、方法对应的拦截器数组:specificInterceptors.
因为Spring AOP和Spring 事务的实现都是基于代理的.所以把这个部分抽取出来,以供参考.
1. 初始化代理工厂:ProxyFactory
protected Object createProxy(
Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {
//..................略
//代理工厂
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
//判断是否targetClass代理不是接口代理
if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
} else {
//如果是接口代理,需要添加接口属性
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
//适配器模式把拿到的拦截器统一封装成Advisor
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
for (Advisor advisor : advisors) {
proxyFactory.addAdvisor(advisor);
}
//创建代理
return proxyFactory.getProxy(getProxyClassLoader());
//...................略
}
拦截器封装为Advisor的适配处理看这边:
@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) {
// 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);
}
getProxy方法主要包含两个步骤:
- 获取代理初始化处理类:AopProxy
- 生成代理
public Object getProxy(ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader);
}
2. 实现代理
2.1 选择代理方式(cglib、jdk)
创建代理的方法createProxy会根据配置以及是否继承接口分别生成Jdk或者Cglib代理
protected Object createProxy(
Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {
//.......................略
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
//生成代理类返回
return proxyFactory.getProxy(getProxyClassLoader());
}
public Object getProxy(ClassLoader classLoader) {
/**
* @see JdkDynamicAopProxy#getProxy(ClassLoader)
* @see CglibAopProxy#getProxy
*/
return createAopProxy()