编程Spring AOP + Hibernate时出错

时间:2016-11-23 15:18:45

标签: java spring hibernate spring-mvc spring-aop

我正在阅读这里提供的示例:https://www.mkyong.com/spring/spring-aop-examples-advice,我尝试实现一个示例,使代码适应我以前的项目。我有一个Web应用程序,可以在数据库中保存给定人员的姓名和国家/地区,我想要拦截"拦截"执行更新或删除等操作。

我是整个Spring + Hibernate世界的新手,所以我不知道我的代码是否错误。所以我在这里留下一些代码示例:

我的项目结构:

  

包装AOP

     
      
  • HijackAroundMethod.java
  •   
     

包裹控制器

     
      
  • PersonController.java
  •   
     

包DAO

     
      
  • PersonDAO.java

  •   
  • PersonDAOImpl.java

  •   
     

包装模型

     
      
  • Person.java
  •   
     

包裹服务

     
      
  • PersonService.java

  •   
  • PersonServiceImpl.java

  •   

建议方法(如前面提到的页面所示):

public class HijackAroundMethod implements MethodInterceptor{

    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {

        System.out.println("Method name: "+ invocation.getMethod().getName());
        System.out.println("Method arguments: " + Arrays.toString(invocation.getArguments()));
        System.out.println("Before executing operation");

        try{
            Object result = invocation.proceed();
            System.out.println("After executing method");
            return result;
        }catch(IllegalArgumentException e){
            System.out.println("Exception catched");
            throw e;
        }
    }

我的DAO课程的一个例子(这里我实现了与DB持久性相关的功能):

@Repository
public class PersonDAOImpl extends HibernateDaoSupport implements PersonDAO {

    private static final Logger logger = LoggerFactory.getLogger(PersonDAOImpl.class);

    @Autowired
    private SessionFactory sessionFactory;

    @Autowired
    public PersonDAOImpl(SessionFactory sessionFactory) {
        super.setSessionFactory(sessionFactory);
    }

    @Override
    @Transactional
    public void addPerson(Person p) {
        Session session = this.sessionFactory.getCurrentSession();
        session.persist(p);
        logger.info("Person saved successfully, Person Details="+p);
    }

    @Override
    @Transactional
    public void updatePerson(Person p) {
        Session session = this.sessionFactory.getCurrentSession();
        session.update(p);
        logger.info("Person updated successfully, Person Details="+p);
    }

这是我添加到servlet-content.xml(我在其中定义bean配置)的内容:

<bean id="PersonDAOImpl" class="com.dacasals.raspertwo.dao.PersonDAOImpl"/>

<bean id="HijackAroundMethod" class="com.dacasals.raspertwo.aop.HijackAroundMethod"/>

<bean id="PersonDAOImplProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
    <property name="target" ref="PersonDAOImpl"/>
    <property name="interceptorNames">
        <list>
            <value>HijackAroundMethod</value>
        </list>
    </property>
</bean>

当我在我的服务器中运行它时(我使用STS 3.8.1和Tomcat 7),我收到以下错误:

org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.dacasals.raspertwo.dao.PersonDAO] is defined: expected single matching bean but found 3: PersonDAOImpl,PersonDAOImplProxy,personDAOImpl
    org.springframework.beans.factory.config.DependencyDescriptor.resolveNotUnique(DependencyDescriptor.java:172)
    org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1106)
    org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1056)
    org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:566)
    org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
    org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:349)
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1219)
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543)
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
    org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
    org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
    org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
    org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:207)
    org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1128)
    org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1056)
    org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:566)
    org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
    org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:349)
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1219)
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543)
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
    org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
    org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
    org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
    org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:751)
    org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:861)
    org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:541)
    org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:668)
    org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:634)
    org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:682)
    org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:553)
    org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:494)
    org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:136)
    javax.servlet.GenericServlet.init(GenericServlet.java:160)
    org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
    org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
    org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1041)
    org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:603)
    org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
    java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    java.lang.Thread.run(Thread.java:745)

我已经在stackoverflow中阅读了一些问题,但我找不到与我相似的任何案例。

2 个答案:

答案 0 :(得分:0)

弹簧配置存在一些误解

当您将注释@Repository放在类PersonDAOImpl上时,通过使用自动扫描,创建一个名为 personDAOImpl 的bean,并且他的bean实现了接口PersonDAO

然后使用配置文件。在这里你宣布:

<bean id="PersonDAOImpl" class="com.dacasals.raspertwo.dao.PersonDAOImpl"/>

在这种情况下,spring创建一个名为 PersonDAOImpl 的新bean,这个bean实现PersonDAO,它与前一个名称有不同的名称(第一个字符是大写)

最后总是在配置文件中声明:

<bean id="PersonDAOImplProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
    <property name="target" ref="PersonDAOImpl"/>
    <property name="interceptorNames">
        <list>
            <value>HijackAroundMethod</value>
        </list>
    </property>
</bean>

这是一个新的“代理bean”,其最终类为PersonDAOImpl,此bean名称为 PersonDAOImplProxy 。此bean也实现了PersonDAO

此时,您有三个不同的bean都实现了相同的接口。豆类是:

  1. personDAOImpl
  2. PersonDAOImpl
  3. PersonDAOImplProxy
  4. 当您尝试使用@Autowired在另一个bean中注入一个bean时,您不能简单地使用以下语法:

    @Autowired
    private PersonDAO myDao;
    

    Spring不知道应该注入3个bean中的哪一个。因此,您必须告诉spring使用其中一个。这是通过使用@Qualifier注释完成的。假设你想要注入代理bean,你应该使用这样的东西:

    @Autowired
    @Qualifier("PersonDAOImplProxy")
    private PersonDAO myDao;
    

    通过这种方式,spring知道它必须注入一个实现接口PersonDAO的bean,它知道你想要使用代理bean

    在任何情况下,我认为您只想使用其中一个bean,因此您应该检查弹簧配置并对其进行优化

    我希望这是有用的

    安吉洛

答案 1 :(得分:0)

好吧,经过几天我决定尝试另一种方式在我的应用程序上使用方面,现在工作正常。

我读过“Spring in action”第4版,我发现了各方面的好例子。我没有使用“Hijack”类,而是使用@ Pointcut,@ After和@Before等语句声明了一个新类。然后,我能够“监听”我的类执行的操作。

虽然我的目标是创建一种通用的方式来“监听”事件 Spring + Hibernate,这是一个好的开始。太糟糕了,我无法运行之前访问过的网站提供的示例。感谢大家的建议,我很快就会再问。