Spring注入接口的实现类报错分析

说明:

1、本实例用的是注解方式,spring配置已省略

2、使用aop管理事务

     <aop:pointcut expression="execution (* com.test.service.impl.*.*(..))" id="services"/>

 

直接看例子:

    一、 A.java

 

package com.test
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class A {
	@Autowired
	private BImpl bImpl;//注入的是接口的实现类
	
	public void save(){
		bImpl.save();
	}
}

 

 

 

 

   二、B.java 

 

package com.test

public interface B {
	public void save();
}

 

 

 

 

   三、BImpl.java  ,B接口的实现类

 

package com.test
import org.springframework.stereotype.Service;

@Service
public class BImpl implements B {
	@Override
	public void save() {
		System.out.println("BImpl.save()");
	}

}

 

 

 

 

异常: 服务启动会报以下错误:

 No matching bean of type [BImpl] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency.

可见bean装配时出现异常

 

源码分析:

   DefaultListableBeanFactory.java

 

//@param type 类A中的引用BImpl的类型
private String[] doGetBeanNamesForType(Class<?> type, boolean includeNonSingletons, boolean allowEagerInit) {
   //所有已定义的bean,此例中beanName为bImpl
   String[] beanDefinitionNames = getBeanDefinitionNames();
   for (String beanName : beanDefinitionNames) {
      ........
      //@param beanName
      //@param type--com.test.BImpl
      boolean matchFound = isTypeMatch(beanName, type);//转AbstractBeanFactory.isTypeMatch()
      ........
   }
}

 

 

AbstractBeanFactory.java

 

public boolean isTypeMatch(String name, Class<?> targetType) throws NoSuchBeanDefinitionException {
	String beanName = transformedBeanName(name);
	Class<?> typeToMatch = (targetType != null ? targetType : Object.class);

	Object beanInstance = getSingleton(beanName, false);
	......
	return ClassUtils.isAssignableValue(typeToMatch, beanInstance);//转ClassUtils.isAssignable()
	......
}

 

 

 ClassUtils.java

 

class ClassUtils {
	......
	//lhsType -- com.test.BImpl
	//rhsType -- 从spring容器中取出Bean
	public static boolean isAssignable(Class<?> lhsType, Class<?> rhsType) {
		//lhsType是否等于或是rhsType表示类的或接口的父类
		if (lhsType.isAssignableFrom(rhsType)) {
			return true;
		}
		......
		return false;
	}
	......
}

 

结论:

1、此例中如果注入的类型为接口B

     lhsType.isAssignableFrom(rhsType)返回为true,启动成功

2、此例中如果注入的类型为BImpl

    A、BImpl实现了接口B,则rhsType为JDK动态代理对象,lhsType.isAssignableFrom(rhsType)返回false,启动失败

    B、BImpl不实现接口B,则rhsType为CGLIB代理对象(继承目标类),lhsType.isAssignableFrom(rhsType)返回true,启动成功

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值