ProxyFactoryBean setTarget setTargetName setTargetClass注意事项

使用ProxyFactoryBean必须使用setTarget或者setTargetName设置被代理对象,否则target对象找不到后续的操作会直接抛出NPE。
setTargetClass并不是用来设置代理对象的,下文将会给出详细解释.
setTargetName("targetName")targetName为被代理对象在BeanFactory中的注册的id.
将ProxyFactoryBean注册到beans.xml中,代码大概是这样的
<bean id="context" class="........"/>
<bean id="proxiedBean" class="org.springframework.aop.framework.ProxyFactoryBean">
	<property name="targetName" value="context"/>
</bean>
此时工厂中同时存在两个context,只不过proxiedBean是一个被代理的context。
如果context是一个controller类,那么上面这两个声明的bean都会向HandlerMapping注册路由地址,将会会导致路由地址重复异常。
或者继承ProxyFactoryBean,直接在构造器中setTarget,代码如下:
public class ContextProxyFactoryBean extends ProxyFactoryBean {
    public ContextProxyFactoryBean() {
        Context context = new Context();
        setTarget(context);
    }
}
Spring的代理机制有两种,JDK提供的动态代理和CGLIB代理
JDK提供的代理只能用来代理接口,CGLIB则可以生成一个继承指定类的新类。
所以AdvisedSupport(ProxyFactoryBean的父类)提供的setTargetClass,就是用来指定当通过CGLIB代理对象时,新生成的代理对象需要继承的类,
当然这个类必须是代理对象的父类,或者是接口,或是代理对象自身的类(不指定时默认该值)。
当然既然要使用CGLIB那么就一定要setProxyTargetClass(true)开启这个开关。
判断逻辑在DefaultAopProxyFactory中,代码如下
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() || Proxy.isProxyClass(targetClass)) {
				return new JdkDynamicAopProxy(config);
			}
			return new ObjenesisCglibAopProxy(config);
		}
		else {
			return new JdkDynamicAopProxy(config);
		}
}


可以看出config.isProxyTargetClass()是判断是否通过CGLIB生成代理类的条件之一。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值