我正在尝试实现一个简单的Spring AOP示例。
使用案例
我有一个光盘(SgtPeppers)类,其中包含艺术家,标题等属性。它有一种播放特定曲目的方法。我创建了一个方面来计算播放曲目的次数。我有一个测试类来测试它。
问题:
光盘类与方面和测试类位于不同的包中。使用spring java config方法配置Bean。但是,自动装配似乎不适用于光盘类。它抛出BeanCreationException。
请找到以下代码: 光盘类(这里,它配置为SgtPeppers)
package com.springinaction.soundsystem.autoconfig;
import java.util.List;
public class SgtPeppers implements CompactDisc {
private String title, artist;
public SgtPeppers(String title, String artist) {
super();
this.title = title;
this.artist = artist;
}
public SgtPeppers() {
// TODO Auto-generated constructor stub
}
public String getTitle() {
return title;
}
public String getArtist() {
return artist;
}
@Override
public void play() {
System.out.println("Playing "+title+" by "+ artist);
}
public void playTrack(int tracknumber) {
System.out.println("Playing track "+ tracknumber);
}
}
TrackCounter看点:
package com.springinaction.aspects.concert.trackCounter;
import java.util.HashMap;
import java.util.Map;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
@Aspect
public class TrackCounter {
private Map<Integer,Integer> trackCounts = new HashMap<Integer, Integer>();
@Pointcut("execution(** com.springinaction.aspects.concert.trackCounter.SgtPeppers.playTrack(int)) && args(trackNumber)")
public void trackPlayed(int trackNumber){}
@Before("trackPlayed(trackNumber)")
public void countTrack(int trackNumber) {
int trackCount = getTrackCount(trackNumber);
trackCounts.put(trackNumber, trackCount+1);
}
public int getTrackCount(int trackNumber) {
return trackCounts.containsKey(trackNumber) ? trackCounts.get(trackNumber) : 0;
}
}
TrackCounterConfig:
package com.springinaction.aspects.concert.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import com.springinaction.aspects.concert.trackCounter.SgtPeppers;
import com.springinaction.aspects.concert.trackCounter.TrackCounter;
@Configuration
@EnableAspectJAutoProxy
public class TrackCounterConfig {
@Bean
public SgtPeppers sgtPeppers() {
SgtPeppers cd = new SgtPeppers("Sgt. Pepper's Lonely Hearts Club Band", "The Beatles");
return cd;
}
@Bean
public TrackCounter trackCounter() {
return new TrackCounter();
}
}
TrackCounterTest:
package com.springinaction.aspects.concert.trackCounter;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.springinaction.aspects.concert.config.TrackCounterConfig;
import com.springinaction.soundsystem.autoconfig.SgtPeppers;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=TrackCounterConfig.class)
public class TrackCounterTest {
@Autowired
private TrackCounter trackCounter;
@Autowired
private SgtPeppers sgtPeppers;
@Test
public void testTrackCounter() {
sgtPeppers.playTrack(1);
sgtPeppers.playTrack(1);
sgtPeppers.playTrack(2);
sgtPeppers.playTrack(2);
sgtPeppers.playTrack(3);
sgtPeppers.playTrack(3);
sgtPeppers.playTrack(3);
sgtPeppers.playTrack(3);
sgtPeppers.playTrack(7);
sgtPeppers.playTrack(7);
assertEquals(2, trackCounter.getTrackCount(1));
assertEquals(2, trackCounter.getTrackCount(2));
assertEquals(4, trackCounter.getTrackCount(3));
assertEquals(2, trackCounter.getTrackCount(7));
}
}
这里,SgtPeppers类位于com.springinaction.soundsystem.autoconfig包中。 TrackCounter和TrackCounterconfig位于com.springinaction.aspects.concert.config包中。我得到以下异常:
org.springframework.beans.factory.BeanCreationException:创建名称为&#39; com.springinaction.aspects.concert.trackCounter.TrackCounterTest&#39;:注册自动连接的依赖项失败;嵌套异常是org.springframework.beans.factory.BeanCreationException:无法自动装配字段:private com.springinaction.soundsystem.autoconfig.SgtPeppers com.springinaction.aspects.concert.trackCounter.TrackCounterTest.sgtPeppers;嵌套异常是org.springframework.beans.factory.NoSuchBeanDefinitionException:找不到[com.springinaction.soundsystem.autoconfig.SgtPeppers]类型的限定bean用于依赖:预期至少有1个bean可以作为此依赖项的autowire候选者。依赖注释:{@ org.springframework.beans.factory.annotation.Autowired(required = true)} at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:293) 在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1186) 在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireBeanProperties(AbstractAutowireCapableBeanFactory.java:384) 在org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:110) 在org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:75) 在org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:331) 在org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:213) 在org.springframework.test.context.junit4.SpringJUnit4ClassRunner $ 1.runReflectiveCall(SpringJUnit4ClassRunner.java:290) 在org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) 在org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:292) 在org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:233) 在org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:87) 在org.junit.runners.ParentRunner $ 3.run(ParentRunner.java:238) 在org.junit.runners.ParentRunner $ 1.schedule(ParentRunner.java:63) 在org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) 在org.junit.runners.ParentRunner.access $ 000(ParentRunner.java:53) 在org.junit.runners.ParentRunner $ 2.evaluate(ParentRunner.java:229) 在org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) 在org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71) 在org.junit.runners.ParentRunner.run(ParentRunner.java:309) 在org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:176) 在org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86) 在org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) 在org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) 在org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678) 在org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) 在org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192) 引起:org.springframework.beans.factory.BeanCreationException:无法自动装配字段:private com.springinaction.soundsystem.autoconfig.SgtPeppers com.springinaction.aspects.concert.trackCounter.TrackCounterTest.sgtPeppers;嵌套异常是org.springframework.beans.factory.NoSuchBeanDefinitionException:找不到[com.springinaction.soundsystem.autoconfig.SgtPeppers]类型的限定bean用于依赖:预期至少有1个bean可以作为此依赖项的autowire候选者。依赖注释:{@ org.springframework.beans.factory.annotation.Autowired(required = true)} at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor $ AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:509) 在org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87) at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:290) ......还有26个 引起:org.springframework.beans.factory.NoSuchBeanDefinitionException:找不到[com.springinaction.soundsystem.autoconfig.SgtPeppers]类型的限定bean用于依赖:预期至少有1个bean符合此依赖关系的autowire候选者。依赖注释:{@ org.springframework.beans.factory.annotation.Autowired(required = true)} at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1118) at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:967) at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:862) at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor $ AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:481) ......还有28个
注意:我尝试过使用basePackages,basePackageClasses的ComponentScan。但是,它没有用。我没有使用弹簧靴配置作为学习目的。
我在com.springinaction.aspects.concert.config包中创建了相同的SgtPeppers bean。自动装配工作。为什么java配置bean创建方式不适用于在不同包中定义的bean?
任何建议都会有所帮助。
感谢。