由于Spring实施了AOP,有时候你想要在同一个班级中调用一个方法来调用你的建议。
这是一个简单的例子
@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
}
}
现在忽略一下,在春天我可以使用@Cached注释进行缓存,我的例子的一点是getSomeValue()被其他bean通过spring代理访问并运行相关的建议。对txnGetSomeValue的内部调用不会,在我的示例中将错过我们在@Transactional切点处应用的建议。
访问代理的最佳方式是什么,以便您可以应用建议?
我最好的方法有效,但很笨拙。它严重暴露了实施。我在几年前就想到这一点并且只是坚持使用这个笨拙的代码,但想知道什么是首选方法。我的hacky方法看起来像这样。
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;
}
}
我所做的是添加BeanNameAware和SpringContextAware,以便我可以在Spring中查找我的代理对象。丑陋,我知道。任何关于更清洁的方法的建议都会很好。
答案 0 :(得分:1)
您可以使用@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
无效。