Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring 什么';在春季访问AOP代理的最佳方式是什么?_Spring_Proxy_Aop - Fatal编程技术网

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

由于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
    }
}
现在暂时忽略一下,在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名称。就是这样!我知道一定有更好的办法,谢谢你的帮助。