2016-11-23 78 views
0

我正在閱讀可在此處獲得的示例:https://www.mkyong.com/spring/spring-aop-examples-advice,並試圖實現一個示例,將代碼調整爲我之前的項目。我有一個單獨的Web應用程序,它將一個給定人員的姓名和國家保存在數據庫中,並且我想要「攔截」更新或刪除操作的執行。編程Spring AOP +休眠時出錯

我是新進入整個Spring + Hibernate世界,所以我不知道我的代碼是否有問題。所以在這裏我要離開你一些代碼示例:

我的項目結構:

Package AOP

  • HijackAroundMethod.java

Package Controller

  • PersonController.java

Package DAO

  • PersonDAO.java

  • PersonDAOImpl.java

Package Model

  • Person.java

Package Service

  • 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類(這裏是我實現與數據庫持久性有關的功能):

@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); 
    } 

這是我加的d我的servlet的content.xml中(其中我定義豆類配置):

<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,但我找不到任何類似於我的情況。

+0

你是否在代碼中的其他地方自動裝配PersonDAO?錯誤的方法導致你自動裝配PersonDAO並且不告訴Spring哪個實現必須被使用 – ZeusNet

+0

請發佈你的完整spring-config並重新檢查它。問題很明顯:'預計單個匹配的bean,但發現3:PersonDAOImpl,PersonDAOImplProxy,personDAOImpl' – AntJavaDev

回答

0

有一些misunderstaning彈簧配置

當你把註釋@Repository的類春天,通過使用自動掃描,創建一個bean叫personDAOImpl和他的bean實現了接口PersonDAO

然後你使用配置文件。在這裏,您聲明此:

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

在這種情況下,春季創建了一個新的bean稱爲PersonDAOImpl這個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的名字是01 PersonDAOImplProxy 。此外,這個bean實現了PersonDAO

在這一點上,你有三個不同的bean都實現相同的接口。豆類:

  1. personDAOImpl
  2. PersonDAOImpl
  3. PersonDAOImplProxy

當您嘗試使用@Autowired你不能簡單地使用在另一個bean注入的bean語法:

@Autowired 
private PersonDAO myDao; 

春天不知道應該注入3個豆中的哪一個。所以你必須告訴spring使用3中的一個。這是通過使用@Qualifier註釋完成的。讓我們假設你想注入proxyed豆你應該使用這樣的事情:

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

這樣春天知道它必須注入一個bean實現接口PersonDAO,它知道你要使用的proxyed豆

在anycase我想你想只使用豆類之一,所以你應該檢查你的Spring配置和優化

我希望這是有用的

安傑洛

+0

嗨@Angelo Immediata,我看看你告訴我什麼。我在servlet-context.xml中刪除了一些bean定義,並且我的應用程序能夠再次運行,但是當我嘗試訪問表單頁面時出現錯誤。控制檯不顯示任何解釋。我只剩下與AOP類相關的bean和代理bean,試圖運行AOP示例,但沒有發生任何事情。 我試圖將註釋限定符添加到我的PersonDAOImpl構造函數,但也出現錯誤。 – Ethan

+0

奇怪的是,在控制檯和/或日誌文件中出現錯誤,沒有堆棧跟蹤。嘗試檢查yuo是否捕獲到任何異常,並且從不打印 –

0

好吧,幾天後,我決定嘗試另一種方式在我的應用程序上使用方面,現在工作正常。

我讀了一本書「Spring in action」第4版,我發現了很多方面的例子。我沒有使用「Hijack」類,而是使用@Pointcut,@After和@Before之類的註解來聲明一個新類。然後,我能夠「聽」我的課程所執行的操作。

雖然我的目標是創建一個通用的方式來在 Spring + Hibernate中「聆聽」事件,但這是一個好的開始。太糟糕了,我無法運行我之前訪問的網站提供的示例。感謝大家的意見,很快我會再問。