可以在Spring中获取给定对象的代理吗?我需要调用子类的函数。但是,显然,当我直接打电话时,方面不适用。这是一个例子:
public class Parent {
public doSomething() {
Parent proxyOfMe = Spring.getProxyOfMe(this); // (please)
Method method = this.class.getMethod("sayHello");
method.invoke(proxyOfMe);
}
}
public class Child extends Parent {
@Secured("president")
public void sayHello() {
System.out.println("Hello Mr. President");
}
}
我找到了实现这一目标的方法。它有效,但我认为不是很优雅:
public class Parent implements BeanNameAware {
@Autowired private ApplicationContext applicationContext;
private String beanName; // Getter
public doSomething() {
Parent proxyOfMe = applicationContext.getBean(beanName, Parent.class);
Method method = this.class.getMethod("sayHello");
method.invoke(proxyOfMe);
}
}
答案 0 :(得分:14)
答案 1 :(得分:13)
AopContext.currentProxy()
将起作用。在代理类之外工作的更通用的解决方案是将对象强制转换为org.springframework.aop.framework.Advised
并获取.getTargetSource().getTarget()
前者(从代理对象获取真实对象)是你不应该真正需要的东西。另一方面,获取目标代理可能在某些检查现有bean的实用程序类中有用,以便添加某些功能。
答案 2 :(得分:8)
您可以使用bean后处理器在目标bean上设置对代理的引用。它将Spring中的Spring特定内容移动到单个类中。
<强>后处理器强>
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
public class SelfReferencingBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof SelfReferencingBean) {
((SelfReferencingBean) bean).setProxy(bean);
}
return bean;
}
}
<强>上下文强>
在applicationContext.xml
注册后处理器。
<bean id="srbpp" class="SelfReferencingBeanPostProcessor"/>
<强>豆强>
每个bean必须实现SelfReferencingBean
告诉后处理器它需要对代理的引用。
public interface SelfReferencingBean {
void setProxy(Object proxy) ;
}
现在在每个需要通过代理调用自身的bean中实现setProxy
。
public class MyBean implements SelfReferencingBean {
MyBean proxy;
@Override
public void setProxy(Object proxy) {
this.proxy = (MyBean) proxy;
}
}
如果在直接调用方法时不介意将proxy
转换为bean的类型,可以将最后一段代码放入bean基类中。由于你正在经历Method.invoke
,你甚至不需要演员。
通过一些工作,我打赌这可以转换为注释处理器la @Autowired
。想想看,我不记得我是否尝试使用@Autowired
本身添加自引用。
public class MyBean implements SelfReferencingBean {
@Autowired MyBean proxy;
}