2015-04-08 63 views
1

由于Spring的AOP实现,有时您想调用同一个类中的方法,您希望该调用通过您的建议。在春天访问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()被通过其他豆类访问春季代理和运行相关的建议。对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中查找我的代理对象。丑陋的我知道。任何建议干净的方式来做到这一点很好。

回答

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将无法​​正常工作。

+0

这正是我期待的那种简单。不幸的是,当我尝试它时,我得到了这个bean创建异常消息。创建名为'someDaoClassImpl'的bean时出错:注入资源依赖关系失败;嵌套异常是org.springframework.beans.factory.NoSuchBeanDefinitionException:找不到符合依赖关系的[SomeDaoClassImpl]类型的合格bean:期望至少1个符合此依赖关系自动装配候选资格的bean。依赖注释 –

+0

@Resource按名称注入,并且只有在未找到时才回退键入。确保您使用的是正确的bean名称。 –

+0

这样做!我知道必须有更好的方式,感谢您的帮助。 –

相关问题