问题描述
有如下一个配置 <context:component-scan base-package="com.myapp.aop.introduce" /> <bean id="forumService" class="org.springframework.aop.framework.ProxyFactoryBean" p:interfaces="com.myapp.aop.introduce.Monitorable" p:target-ref="forumServiceTarget" p:interceptorNames="pmonitor" p:proxyTargetClass="true" /> 在第一个测试中 @Test public void test() { String configPath = "/aop/introduce/applicationContext.xml"; ApplicationContext ctx = new ClassPathXmlApplicationContext(configPath); ForumService forumService = (ForumService) ctx.getBean("forumService"); forumService.removeForum(10); forumService.removeTopic(1022); Monitorable moniterable = (Monitorable) forumService; moniterable.setMonitorActive(true); forumService.removeForum(10); forumService.removeTopic(1022); }可以正常运行 通过@ContextConfiguration加载配置文件,方法如下 @RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(locations = { "/aop/introduce/applicationContext.xml" })public class ForumServiceTest{ @Autowired @Qualifier(value = "forumService") ForumService forumService; @Test public void test() { forumService.removeForum(10); forumService.removeTopic(1022); Monitorable moniterable = (Monitorable)forumService; moniterable.setMonitorActive(true); forumService.removeForum(10); forumService.removeTopic(1022); }}抛出org.springframework.beans.factory.NoSuchBeanDefinitionException的异常,指向forumService不存在 其他主要代码:public interface Monitorable{ void setMonitorActive(boolean active);}@Component(value = "pmonitor")public class ControllablePerformaceMonitor extends DelegatingIntroductionInterceptor implements Monitorable{ private static final long serialVersionUID = 7120067058565963790L; private ThreadLocal<Boolean> MonitorStatusMap = new ThreadLocal<Boolean>(); public void setMonitorActive(boolean active) { MonitorStatusMap.set(active); } public Object invoke(MethodInvocation mi) throws Throwable { Object obj = null; if (MonitorStatusMap.get() != null && MonitorStatusMap.get()) { PerformanceMonitor.begin(mi.getClass().getName() + "." + mi.getMethod().getName()); obj = super.invoke(mi); PerformanceMonitor.end(); } else { obj = super.invoke(mi); } return obj; }}@Component(value = "forumServiceTarget")public class ForumService{ public void removeTopic(int topicId) { System.out.println("模拟删除Topic记录:" + topicId); try { Thread.currentThread().sleep(20); } catch (Exception e) { throw new RuntimeException(e); } } public void removeForum(int forumId) { System.out.println("模拟删除Forum记录:" + forumId); try { Thread.currentThread().sleep(40); } catch (Exception e) { throw new RuntimeException(e); } }} 注:通过第二种方式测试AOP的前置、后置、环绕、异常后置增强均通过@ContextConfiguration(locations = { "classpath:/aop/introduce/applicationContext.xml" }) 这么写也不行
解决方案
@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(locations = { "classpath:aop/introduce/applicationContext.xml" })public class ForumServiceTest{ @Autowired private ApplicationContext ctx; @Test public void test() { ForumService forumService = ctx.getBean("forumService", ForumService.class); forumService.removeForum(10); forumService.removeTopic(1022); Monitorable moniterable = (Monitorable)forumService; moniterable.setMonitorActive(true); forumService.removeForum(10); forumService.removeTopic(1022); }}你暂时先通过如上代码实现吧 具体原因 和 spring-data-jpa 与shiro集成时的原因类似,,后边我会专门写篇文章介绍 为什么
解决方案二:
代码分析已经搞定,请参考http://jinnianshilongnian.iteye.com/blog/1894973