编程时出错 Spring AOP+Hibernate
Error while programing Spring AOP+Hibernate
我正在阅读此处提供的示例:https://www.mkyong.com/spring/spring-aop-examples-advice,并尝试实现一个示例,使代码适应我之前的项目。我有一个单独的 Web 应用程序,它在数据库中保存给定人员的姓名和国家/地区,我想 "intercept" 执行更新或删除等操作。
我是整个 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 示例 class(这里是我实现与 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(我定义 beans 配置的地方):
<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.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.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)
我一直在 Whosebug 中阅读一些问题,但我找不到任何与我相似的案例。
spring 配置有一些误解
当您将注释 @Repository
放在 class PersonDAOImpl
spring 上时,通过使用自动扫描,创建一个名为 personDAOImpl[=59 的 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>
这是一个新的 "proxied bean",它的最终 class 是 PersonDAOImpl
,这个 bean 名称是 PersonDAOImplProxy。此 bean 还实现了 PersonDAO
此时您拥有三个不同的 bean,它们都实现了相同的接口。豆子是:
- personDAOImpl
- PersonDAOImpl
- PersonDAOImplProxy
当您尝试使用 @Autowired
将一个 bean 注入另一个 bean 时,您不能简单地使用此语法:
@Autowired
private PersonDAO myDao;
Spring 不知道应该注入 3 个 bean 中的哪一个。所以你必须告诉 spring 使用 3 个中的一个。这是通过使用 @Qualifier
注释来完成的。假设你想注入代理 bean,你应该使用这样的东西:
@Autowired
@Qualifier("PersonDAOImplProxy")
private PersonDAO myDao;
这样 spring 知道它必须注入一个实现接口的 bean PersonDAO
并且它知道你想使用代理 bean
无论如何我认为您只想使用其中一个 bean,因此您应该检查 spring 配置并优化它
我希望这是有用的
安杰洛
好吧,几天后我决定尝试另一种方法来在我的应用程序上使用方面,现在工作正常。
我读了书"Spring in action"第4版,我发现那里有很好的方面的例子。我没有使用 "Hijack" class,而是使用 @Pointcut、@After 和 @Before 等注解声明了一个新的 class。然后,我能够 "listen" 我的 class 执行的操作。
虽然我的目标是创建一种通用的方式来处理 "listen" 中的事件
Spring+Hibernate,这是一个好的开始。太糟糕了,我无法 运行 我之前访问过的网站提供的示例。感谢大家的指教,过段时间再请教
我正在阅读此处提供的示例:https://www.mkyong.com/spring/spring-aop-examples-advice,并尝试实现一个示例,使代码适应我之前的项目。我有一个单独的 Web 应用程序,它在数据库中保存给定人员的姓名和国家/地区,我想 "intercept" 执行更新或删除等操作。
我是整个 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 示例 class(这里是我实现与 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(我定义 beans 配置的地方):
<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.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.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)
我一直在 Whosebug 中阅读一些问题,但我找不到任何与我相似的案例。
spring 配置有一些误解
当您将注释 @Repository
放在 class PersonDAOImpl
spring 上时,通过使用自动扫描,创建一个名为 personDAOImpl[=59 的 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>
这是一个新的 "proxied bean",它的最终 class 是 PersonDAOImpl
,这个 bean 名称是 PersonDAOImplProxy。此 bean 还实现了 PersonDAO
此时您拥有三个不同的 bean,它们都实现了相同的接口。豆子是:
- personDAOImpl
- PersonDAOImpl
- PersonDAOImplProxy
当您尝试使用 @Autowired
将一个 bean 注入另一个 bean 时,您不能简单地使用此语法:
@Autowired
private PersonDAO myDao;
Spring 不知道应该注入 3 个 bean 中的哪一个。所以你必须告诉 spring 使用 3 个中的一个。这是通过使用 @Qualifier
注释来完成的。假设你想注入代理 bean,你应该使用这样的东西:
@Autowired
@Qualifier("PersonDAOImplProxy")
private PersonDAO myDao;
这样 spring 知道它必须注入一个实现接口的 bean PersonDAO
并且它知道你想使用代理 bean
无论如何我认为您只想使用其中一个 bean,因此您应该检查 spring 配置并优化它
我希望这是有用的
安杰洛
好吧,几天后我决定尝试另一种方法来在我的应用程序上使用方面,现在工作正常。
我读了书"Spring in action"第4版,我发现那里有很好的方面的例子。我没有使用 "Hijack" class,而是使用 @Pointcut、@After 和 @Before 等注解声明了一个新的 class。然后,我能够 "listen" 我的 class 执行的操作。
虽然我的目标是创建一种通用的方式来处理 "listen" 中的事件 Spring+Hibernate,这是一个好的开始。太糟糕了,我无法 运行 我之前访问过的网站提供的示例。感谢大家的指教,过段时间再请教