Spring 什么';在春季访问AOP代理的最佳方式是什么?
由于Spring实现了AOP,有时您希望在同一个类中调用一个方法,希望调用传递您的建议 这里有一个简单的例子Spring 什么';在春季访问AOP代理的最佳方式是什么?,spring,proxy,aop,Spring,Proxy,Aop,由于Spring实现了AOP,有时您希望在同一个类中调用一个方法,希望调用传递您的建议 这里有一个简单的例子 @Service public class SomeDaoClass { public int getSomeValue() { // do some cache look up Integer cached = ...; if ( cached == null ) { cached = txnGetSome
@Service
public class SomeDaoClass {
public int getSomeValue() {
// do some cache look up
Integer cached = ...;
if ( cached == null ) {
cached = txnGetSomeValue();
// store in cache
}
return cached;
}
@Transactional
public int txnGetSomeValue() {
// look up in database
}
}
现在暂时忽略一下,在spring中,我可以使用@Cached注释进行缓存,我的示例的要点是,其他bean通过spring代理并运行相关的通知来访问getSomeValue()。对txnGetSomeValue的内部调用不会,在我的示例中,将错过我们在@Transactional切入点应用的建议
访问您的代理以应用建议的最佳方式是什么
我最好的方法是有效的,但很笨拙。它严重暴露了实现。我几年前就发现了这一点,并且一直在使用这段笨拙的代码,但我想知道首选的方法是什么。我的方法看起来像这样
public interface SomeDaoClass {
public int getSomeValue();
// sometimes I'll put these methods in another interface to hide them
// but keeping them in the primary interface for simplicity.
public int txnGetSomeValue();
}
@Service
public class SomeDaoClassImpl implements SomeDaoClass, BeanNameAware, ApplicationContextAware {
public int getSomeValue() {
// do some cache look up
Integer cached = ...;
if ( cached == null ) {
cached = proxy.txnGetSomeValue();
// store in cache
}
return cached;
}
@Transactional
public int txnGetSomeValue() {
// look up in database
}
SomeDaoClass proxy = this;
String beanName = null;
ApplicationContext ctx = null;
@Override
public void setBeanName(String name) {
beanName = name;
setProxy();
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
ctx = applicationContext;
setProxy();
}
private void setProxy() {
if ( beanName == null || ctx == null )
return;
proxy = (BlockDao) ctx.getBean(beanName);
beanName = null;
ctx = null;
}
}
我所做的是添加BeanNameware和SpringContextAware,以便在Spring中查找我的代理对象。我知道。任何关于更干净的方法的建议都很好。您可以使用
@Resource
@Service
public class SomeDaoClassImpl implements SomeDaoClass {
@Resource
private SomeDaoClassImpl someDaoClassImpl;
public int getSomeValue() {
// do some cache look up
Integer cached = ...;
if ( cached == null ) {
cached = somDaoClassImpl.txnGetSomeValue();
// store in cache
}
return cached;
}
@Transactional
public int txnGetSomeValue() {
// look up in database
}
注意:
@Autowired
不起作用。这正是我想要的那种简单性。不幸的是,当我尝试它时,我得到了这个bean创建异常消息。创建名为“someDaoClassImpl”的bean时出错:注入资源依赖项失败;嵌套异常为org.springframework.beans.factory.NoSuchBeanDefinitionException:未找到依赖项类型为[SomeDaoClassImpl]的符合条件的bean:应至少有1个bean符合此依赖项的autowire候选项的条件。附属国annotations@Resource按名称注入,仅在未找到时回退到类型。确保您使用的是正确的bean名称。就是这样!我知道一定有更好的办法,谢谢你的帮助。