《Spring IN Action 》读书笔记错误记录之org.springframework.beans.factory.BeanNotOfRequiredTypeException

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/LJX_ahut/article/details/81988368

小菜鸟学习spring,最近在啃 Spring IN ACTION ,中文版书名为spring实战,本书被大多数人点赞和好评。为了提高学习效果,特此做一个简单的笔记以便温习回顾,如有错误或者您有更好的建议与意见烦请指正指导。

 报错信息摘要如下:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.lujx.concert.test.TestAudience': 
Unsatisfied dependency expressed through field 'magicShow'; nested exception is org.springframework.beans.factory.BeanNotOfRequiredTypeException:
 Bean named 'magicShow' is expected to be of type 'org.lujx.concert.test.MagicShow' but was actually of type 'com.sun.proxy.$Proxy25'
Caused by: org.springframework.beans.factory.BeanNotOfRequiredTypeException: 
Bean named 'magicShow' is expected to be of type 'org.lujx.concert.test.MagicShow' but was actually of type 'com.sun.proxy.$Proxy25'

报错信息来自一个spring的AOP应用的一个demo,结构如下图

其中,Performance是一个接口,Audience是一个切面类,定义了几个切面逻辑,ConcertConfig.java是配置类,在测试包里,MagicShow是Performance接口的实现类;

ConcertConfig.java源码如下,可以看到,配置中启用了AspectJ自动代理和组件扫描,并且以java装配的方式注入了切面类bean

package org.lujx.concert;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

@Configuration
@ComponentScan    //启动spring组件扫描
@EnableAspectJAutoProxy   //启动AspectJ自动代理
public class ConcertConfig {

	//使用java装配方式注入bean
	@Bean
	public Audience audience(){
		return new Audience();
	}
}

测试类代码如下。

package org.lujx.concert.test;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.lujx.concert.ConcertConfig;
import org.lujx.concert.Performance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)  //使用spring单元测试
@ContextConfiguration(classes=ConcertConfig.class)   //引入配置类
public class TestAudience {

    // 定义接口实现类。由于JDK动态代理不支持类注入,所以程序在此处抛出异常
	@Autowired
	private MagicShow magicShow;
		
	@Test
	public void testPointCut(){
		magicShow.perform();
	}
}

可以看到,测试类中注入了一个接口实现类,由于spring的代理机制,JDK的动态代理不支持类注入,只支持接口注入,所以解决这个异常的方法有两种:

第一种:改类注入为接口注入,即

// 定义接口实现类。由于JDK动态代理不支持类注入,所以程序在此处抛出异常
//@Autowired
//private MagicShow magicShow;

// 使用接口注入
@Autowired
private Performance magicShow;

第二种,设置ASpectJ自动代理属性,即ConcertConfig.java 文件的注解

//@EnableAspectJAutoProxy

//设置proxyTargetClass属性,可解决JDK动态代理类注入抛出的BeanNotOfRequiredTypeException异常
@EnableAspectJAutoProxy(proxyTargetClass=true)  //启动AspectJ自动代理

特此记录,以便参考。

参考资料:

https://blog.csdn.net/jyp360/article/details/70215002

扫描二维码关注公众号,回复: 2975861 查看本文章

https://blog.csdn.net/u014308482/article/details/53033847

PS:附上其他几个类的源代码

package org.lujx.concert;
public interface Performance {
	void perform();
}
package org.lujx.concert;

import org.apache.log4j.Logger;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

import net.bytebuddy.asm.Advice.This;

@Aspect
public class Audience {
	private Logger LOGGER=Logger.getLogger(This.class);
	
	//定义切入点
	@Pointcut("execution(* org.lujx.concert.Performance.perform(..))")
	public void performance(){ }	
	
	@Before("performance()")
	public void silenceCellPhone(){
		LOGGER.info("Silence The CellPhone");
	}
	
	@Before("performance()")
	public void takeSeats(){
	LOGGER.info("Taking Seats");
	}
	
	@AfterReturning("performance()")
	public void applause(){
		LOGGER.info("CLAP! CLAP! CLAP!!");
	}
	
	@AfterThrowing("performance()")
	public void demandRefund(){
		LOGGER.info("Demanding a refund");
	}
}

package org.lujx.concert.test;

import org.apache.log4j.Logger;
import org.lujx.concert.Performance;
import org.springframework.stereotype.Component;

import net.bytebuddy.asm.Advice.This;

@Component
public class MagicShow implements Performance{
	private Logger LOGGER=Logger.getLogger(This.class);
	
	public void perform() {
		LOGGER.warn("the singer has started to singing !");		
		return;
	}

}

猜你喜欢

转载自blog.csdn.net/LJX_ahut/article/details/81988368