十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
本篇内容介绍了“spring中代理的创建方法有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

创新互联公司是一家集网站建设,准格尔企业网站建设,准格尔品牌网站建设,网站定制,准格尔网站建设报价,网络营销,网络优化,准格尔网站推广为一体的创新建站企业,帮助传统企业提升企业形象加强企业竞争力。可充分满足这一群体相比中小企业更为丰富、高端、多元的互联网需求。同时我们时刻保持专业、时尚、前沿,时刻以成就客户成长自我,坚持不断学习、思考、沉淀、净化自己,让我们为更多的企业打造出实用型网站。
spring 中创建代理使用了 Jdk 和 Cglib 两种方式创建,JdkDynamicAopProxy 和 ObjenesisCglibAopProxy,通过使用配置 Advised 和 ProxyConfig来管理配置,根据配置决定使用哪种方式创建代理,下面来介绍这几个关键的类。
Advised 是一个管理 AOP 代理工厂配置的接口,在spring中的所有AopProxy都可以转换为 Advised。
在 spring 中,使用 ProxyConfig 来配置代理创建属性。
/**
* 代理工厂的超类,用于统一管理代理工厂类的属性。
*/
public class ProxyConfig implements Serializable {
// true:使用子类代理,false:使用接口代理
private boolean proxyTargetClass = false;
// 启动代理优化
private boolean optimize = false;
// 使用该代理工长创建的代理是否可以转换为 Advised,默认为false:表示可以,
// 如果为false,可以将bean转换为Advised:Advised testBean = (Advised) context.getBean("testBean");
boolean opaque = false;
// 将代理暴露出去,绑定到 ThreadLocal 的 currentProxy,用于代理类自己的方法调用自己的场景。
boolean exposeProxy = false;
// 冻结配置,true:不能修改该代理工长的配置。
private boolean frozen = false;
}实现了ProxyConfig 的直接子类有4个:
ScopedProxyFactoryBean、ProxyProcessorSupport、AbstractSingletonProxyFactoryBean、AdvisedSupport,这几个类使用不同的方式来创建代理,但是最后还是会将创建代理的工作委托给 ProxyFactory,下面来查看4个直接子类的相关代码。
ScopedProxyFactoryBean:用于@Scope 注解,实现bean的作用域控制。他实现了 BeanFactory 、BeanFactoryAware接口,具有创建、管理bean的能力。
这个类生成的代理只会记录类的名称,然后根据作用域获取bean,如果是prototype的,则beanFactory会创建一个新的bean。
public class ScopedProxyFactoryBean extends ProxyConfig implements FactoryBean
ProxyProcessorSupport:为 ProxyFactory 提供了常用的公共方法。
public class ProxyProcessorSupport extends ProxyConfig implements Ordered, BeanClassLoaderAware, AopInfrastructureBean {
/**
* 可以自定义排序
*/
public void setOrder(int order) { this.order = order; }
@Override
public int getOrder() { return this.order; }
/**
* 当实现了接口时,使用接口代理,没有实现接口则使用类代理。
*/
protected void evaluateProxyInterfaces(Class> beanClass, ProxyFactory proxyFactory) {
Class>[] targetInterfaces = ClassUtils.getAllInterfacesForClass(beanClass, getProxyClassLoader());
boolean hasReasonableProxyInterface = false;
for (Class> ifc : targetInterfaces) {
if (!isConfigurationCallbackInterface(ifc) && !isInternalLanguageInterface(ifc) &&
ifc.getMethods().length > 0) {
hasReasonableProxyInterface = true;
break;
}
}
if (hasReasonableProxyInterface) {
for (Class> ifc : targetInterfaces) {
proxyFactory.addInterface(ifc);
}
}
else {
proxyFactory.setProxyTargetClass(true);
}
}
}AbstractSingletonProxyFactoryBean : 创建单例代理对象,在需要代理的对象实例化后,使用 InitializingBean#afterPropertiesSet()来创建代理,并为其设置前置通知和后置通知。
public abstract class AbstractSingletonProxyFactoryBean extends ProxyConfig implements FactoryBean
AdvisedSupport:实现了 Advised,将 ProxyConfig与 Advised进行适配,为 Advised 提供了支持,他的唯一子类 ProxyCreatorSupport为创建代理提供了支持。
public class AdvisedSupport extends ProxyConfig implements Advised {
// 空代理对象
public static final TargetSource EMPTY_TARGET_SOURCE = EmptyTargetSource.INSTANCE;
// 代理目标源:默认为空目标源
TargetSource targetSource = EMPTY_TARGET_SOURCE;
// 是否已经对Advisors进行了过虑
private boolean preFiltered = false;
// Advisor 调用链工长
AdvisorChainFactory advisorChainFactory = new DefaultAdvisorChainFactory();
// 缓存方法对应的 Advisor 调用链。
private transient Map> methodCache;
// 要实现的代理接口,按顺序存储。
private List> interfaces = new ArrayList<>();
// Advisor 列表
private List advisors = new ArrayList<>();
// Advisor 数据,为了方便内部操作。
private Advisor[] advisorArray = new Advisor[0];
} ProxyCreatorSupport 为创建代理提供了支持,他使用了AopProxyFactory 来创建AopProxy,最后ProxyFactory使用 AopProxy来创建代理对象。
在创建ProxyCreatorSupport 时默认创建 DefaultAopProxyFactory,由他来判断使用接口代理还是子类代理。
public class ProxyCreatorSupport extends AdvisedSupport {
private AopProxyFactory aopProxyFactory;
private final List listeners = new LinkedList<>();
// 在创建第一个代理后将置为true,表示进入活动状态,将会触发 listeners。
private boolean active = false;
/**
* 无参构造器,将会创建一个默认的aopProxyFactory。
* DefaultAopProxyFactory 是一个创建代理的工长,用于根据配置创建代理。
*/
public ProxyCreatorSupport() {
this.aopProxyFactory = new DefaultAopProxyFactory();
}
// 创建AOP代理,根据自身的配置属性觉得使用JDK代理还是Cglib代理。
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
return getAopProxyFactory().createAopProxy(this);
}
} 上面提到使用 DefaultAopProxyFactory 来决定使用 jdk代理还是 Cglib代理,他通过接收一个 AdvisedSupport
// AopProxy 工厂
public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
@Override
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.");
}
// 代理目标是接口,或者也是一个代理对象,使用jdk代理,否则使用Cglib 代理
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
}
// 使用接口代理:JDK代理
else {
return new JdkDynamicAopProxy(config);
}
}
}ProxyFactory 是ProxyCreatorSupport 的子类,通过调用父类的方法获取AopProxy来创建目标代理对象。
public class ProxyFactory extends ProxyCreatorSupport {
public Object getProxy() {
// 掉用 `ProxyCreatorSupport#createAopProxy` 方法之后根据配置来判断使用 JDK生成代理还是 Cglib生成代理
return createAopProxy().getProxy();
}
// 与上面的方法区别在于传入了类加载器
public Object getProxy(@Nullable ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader);
}
}final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {
/** 代理配置. */
private final AdvisedSupport advised;
/**
* 代理的接口上是否定义了equals方法
*/
private boolean equalsDefined;
/**
* 代理的接口是否定义了hashCode 方法
*/
private boolean hashCodeDefined;
public JdkDynamicAopProxy(AdvisedSupport config) throws AopConfigException {
Assert.notNull(config, "AdvisedSupport must not be null");
// 通知不为空,并且目标源不为空。
if (config.getAdvisors().length == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) {
throw new AopConfigException("No advisors and no TargetSource specified");
}
this.advised = config;
}
// 创建代理
@Override
public Object getProxy() {
// 传入默认类加载器
return getProxy(ClassUtils.getDefaultClassLoader());
}
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
}
// 获取代理目标类的所有接口
Class>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
// 检查接口是否实现了equals 和 hashCode 方法
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
// 创建代理对象,这里传入了this对象,因为 JdkDynamicAopProxy 实现了 InvocationHandler,使用这一段代理逻辑进行代理
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
/**
* aop代理使用jdk代理将执行的逻辑
*/
@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 {
// 执行equals方法时,接口未定义 equals 方法 ,执行JdkDynamicAopProxy 的 equals 方法
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
return equals(args[0]);
}
// 执行 hashCode 方法时,接口未定义 hashCode 方法,执行JdkDynamicAopProxy的hashCode方法
else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
return hashCode();
}
//
else if (method.getDeclaringClass() == DecoratingProxy.class) {
return AopProxyUtils.ultimateTargetClass(this.advised);
}
// 能够转换为Advised,将转换为Advised,然后执行
else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
method.getDeclaringClass().isAssignableFrom(Advised.class)) {
return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
}
Object retVal;
// 是否暴露当前的代理,绑定到ThreadLocal中,
if (this.advised.exposeProxy) {
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
// 获取目标对象
target = targetSource.getTarget();
Class> targetClass = (target != null ? target.getClass() : null);
// 根据代理目标对象和方法获取切入点、方法拦截器等。
List在 JdkDynamicAopProxy 中,有2处关键代码,1是获取代理目标的接口,2是执行切入点、拦截器。
AopProxyUtils#completeProxiedInterfaces()方法获取代理目标的接口,按照规则添加一部分接口SpringProxy、Advised、DecoratingProxy。
// AopProxyUtils
static Class>[] completeProxiedInterfaces(AdvisedSupport advised, boolean decoratingProxy) {
// 获取目标类实现的接口接口
Class>[] specifiedInterfaces = advised.getProxiedInterfaces();
// 目标类的接口为空
if (specifiedInterfaces.length == 0) {
// 获取代理目标class
Class> targetClass = advised.getTargetClass();
if (targetClass != null) {
// 判断目标类型是否是接口
if (targetClass.isInterface()) {
advised.setInterfaces(targetClass);
}
// 代理目标类型是代理
else if (Proxy.isProxyClass(targetClass)) {
advised.setInterfaces(targetClass.getInterfaces());
}
// 重新获取代理对象的接口集
specifiedInterfaces = advised.getProxiedInterfaces();
}
}
// 如果目标类未实现 SpringProxy 接口,将添加 SpringProxy 到接口集中。
boolean addSpringProxy = !advised.isInterfaceProxied(SpringProxy.class);
// 目标类能转换为Advised,并且未实现 Advised 接口,则添加 Advised 到接口集中
boolean addAdvised = !advised.isOpaque() && !advised.isInterfaceProxied(Advised.class);
// decoratingProxy 为true,且目标类未实现 DecoratingProxy 接口,将 DecoratingProxy 添加进接口集中
boolean addDecoratingProxy = (decoratingProxy && !advised.isInterfaceProxied(DecoratingProxy.class));
// 划分接口数组长度
int nonUserIfcCount = 0;
if (addSpringProxy) {
nonUserIfcCount++;
}
if (addAdvised) {
nonUserIfcCount++;
}
if (addDecoratingProxy) {
nonUserIfcCount++;
}
Class>[] proxiedInterfaces = new Class>[specifiedInterfaces.length + nonUserIfcCount];
// 拷贝
System.arraycopy(specifiedInterfaces, 0, proxiedInterfaces, 0, specifiedInterfaces.length);
// 将接口class设置进对应的数组位置
int index = specifiedInterfaces.length;
if (addSpringProxy) {
proxiedInterfaces[index] = SpringProxy.class;
index++;
}
if (addAdvised) {
proxiedInterfaces[index] = Advised.class;
index++;
}
if (addDecoratingProxy) {
proxiedInterfaces[index] = DecoratingProxy.class;
}
// 返回需要代理的接口集。
return proxiedInterfaces;
} 执行切面和方法拦截器逻辑 ReflectiveMethodInvocation#proceed
public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Cloneable {
public Object proceed() throws Throwable {
// 执行完后通知或拦截器后,将执行业务方法
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
// 获取通知或拦截器
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
// 通知或拦截器是 InterceptorAndDynamicMethodMatcher
// InterceptorAndDynamicMethodMatcher 用于将方法匹配器与拦截器结合,如果方法匹配器匹配了就是用拦截器进行调用
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();
}
}
// 调用其他拦截器,其他拦截器需要调用,因为传入了this,拦截器链可以使用引用调用本方法,以执行下一个切面或拦截器。
else {
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
}“spring中代理的创建方法有哪些”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注创新互联网站,小编将为大家输出更多高质量的实用文章!