我在春天学习AOP时遇到了一个非常奇怪的异常。
以下是我的代码:
CompactDisc界面:
public interface CompactDisc {
void play();
}
BlankDisc类:
import org.springframework.stereotype.Component;
import java.util.List;
@Component
public class BlankDisc implements CompactDisc {
private String title;
private String artist;
private List<String> tracks;
public BlankDisc(String title, String artist, List<String> tracks) {
this.title = title;
this.artist = artist;
this.tracks = tracks;
}
@Override
public void play() {
System.out.println("Playing "+title+" by "+artist);
for (String track : tracks)
System.out.println("-Track "+track);
}
public void playTrack(int trackNumber) {
System.out.println("-Track "+tracks.get(trackNumber));
}
TrackCounter类
package soundsystem;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import java.util.HashMap;
import java.util.Map;
@Aspect
public class TrackCounter {
private Map<Integer,Integer> trackCounts = new HashMap<>();
@Pointcut("execution(* BlankDisc.playTrack(int)) " +
"&& args(trackNumber)")
public void trackPlayed(int trackNumber) {}
@Before("trackPlayed(trackNumber)")
public void countTrack(int trackNumber) {
int currentCount = getPlayCount(trackNumber);
trackCounts.put(trackNumber, currentCount + 1);
}
public int getPlayCount(int trackNumber) {
return trackCounts.getOrDefault(trackNumber, 0);
}
}
TrackCounterConfig类
package soundsystem;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import java.util.ArrayList;
import java.util.List;
@Configuration
@EnableAspectJAutoProxy
public class TrackCounterConfig {
@Bean(name = "compactDisc")
public BlankDisc blankDisc() {
List<String> list= new ArrayList<>(5);
list.add("Sgt.Pepper's Lonely Hearts Club Band");
list.add("With a Little Help from My Friends");
list.add("Lucy in the Sky with Diamonds");
list.add("Getting Better");
list.add("Fixing a Hole");
return new BlankDisc("Sgt.Pepper's Lonely Hearts Club Band","The Beatles",list);
}
@Bean
public TrackCounter trackCounter() {
return new TrackCounter();
}
}
TrackCounterTest类:
import static org.junit.Assert.*;
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 soundsystem.*;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = TrackCounterConfig.class)
public class TrackCounterTest {
@Autowired
private BlankDisc cd;
@Autowired
private TrackCounter counter;
@Test
public void testTrackCounter() {
//Question: cd must be CompactDisc not BlankDisc,
//otherwise will cause type exception, why?
cd.playTrack(0);
cd.playTrack(1);
cd.playTrack(2);
cd.playTrack(3);
cd.playTrack(3);
cd.playTrack(3);
cd.playTrack(3);
cd.playTrack(4);
assertEquals(1,counter.getPlayCount(1));
assertEquals(1,counter.getPlayCount(0));
assertEquals(1,counter.getPlayCount(2));
assertEquals(4,counter.getPlayCount(3));
assertEquals(1,counter.getPlayCount(4));
}
}
我跑了测试,然后我有例外:
Caused by: org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'compactDisc' is expected to be of type 'soundsystem.BlankDisc' but was actually of type 'com.sun.proxy.$Proxy22'
at org.springframework.beans.factory.support.DefaultListableBeanFactory.checkBeanNotOfRequiredType(DefaultListableBeanFactory.java:1510)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1489)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1104)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585)
问题是:
1.如果我将cd
中TrackCounterTest
的类型从BlankDisc
更改为CompactDisc
,则不会发生异常,为什么?
2.第一个问题解决后,如果我未在界面void playTrack(int)
中声明方法CompactDisc
,则测试类中的assertEquals()
将失败。也就是说,AOP不起作用,为什么?
我花了一整天的时间研究这个问题,在搜索谷歌后我仍然无法找到答案。由于我是春天的新秀,我真诚地希望有人能帮助我解决这个问题。
谢谢!!!
答案 0 :(得分:0)
这个问题是因为自动装配类型类的bean而不是实现的接口: 请检查此stackoverflow链接,该链接解释了同样的问题:
BeanNotOfRequiredTypeException issue stackoverflow explanation