我正在阅读这里提供的示例: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中阅读了一些问题,但我找不到与我相似的任何案例。
答案 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都实现了相同的接口。豆类是:
当您尝试使用@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,这是一个好的开始。太糟糕了,我无法运行之前访问过的网站提供的示例。感谢大家的建议,我很快就会再问。