这篇博客是在https://blog.csdn.net/qq_37591637/article/details/85156536 这个基础上讲述的
当一个类中有另一个类的属性的时候,在这个类利用另一个类的属性去调另一个类的方法,如果没有set和get方法,就会报空指针异常;
注解提供了自动装配的功能帮我们解决了这个问题
@Autowired 注解自动装配具有兼容类型的单个 Bean属性
构造器, 普通字段(即使是非 public), 一切具有参数的方法都可以应用@Authwired 注解
前提是都被注解了
以下是这个包下面的代码
package cn.com.bean.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import cn.com.bean.service.ServicesTest;
@Controller(value="Controllers")
public class ControllerClass implements ControllInter{
/*当一个类中有另一个类的属性的时候,在这个类利用另一个类的属性去调另一个类的方法
* 如果没有set和get方法,就会报空指针异常;
* 注解提供了自动装配的功能帮我们解决了这个问题@Authwired
*/
@Autowired
private ServicesTest se;
@Override
public void save() {
// TODO Auto-generated method stub
System.out.println("标识表现层组件--我实现了ControllInter接口的save方法....");
se.sevice();
}
}
package cn.com.bean.controller;
public interface ControllInter {
void save();
}
package cn.com.bean.Respository;
import org.springframework.stereotype.Repository;
@Repository(value="res")
public class TRespository {
public void respon(){
System.out.println("标识持久层组件.....");
}
}
package cn.com.bean.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import cn.com.bean.Respository.TRespository;
@Service
public class ServicesTest {
@Autowired
private TRespository cc;
public void sevice() {
System.out.println("标识服务层(业务层)组件....");
cc.respon();
}
}
测试类如下
package cn.com.bean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import cn.com.bean.controller.ControllerClass;
public class TestMain {
/*
* author:命运的信徒 date:2018/12/21 arm:注解的方式来配置bean与bean之间的关系
*/
public static void main(String[] args) {
// 1.创建IOC容器
ApplicationContext ioc = new ClassPathXmlApplicationContext(
"bean-bean.xml");
// 2.
ControllerClass cc = (ControllerClass) ioc.getBean("Controllers");
cc.save();
}
}
配置文件bean-bean.xml
结果如下
自动装配是不是省了很多的set和get方法呢?
不过这上面的实现都是在Spring文件被扫描过的,也就是文件上面有一个S的标志,如果是调用普通的类里面的方法的话,怎么办呢》
继续往下看
默认情况下, 所有使用 @Authwired 注解的属性都需要被设置. 当 Spring 找不到匹配的 Bean 装配属性时, 会抛出异常, 若某一属性允许不被设置, 可以设置 @Authwired 注解的 required 属性为 false
例如在这个类中使用非注解类
package cn.com.bean.Respository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import cn.com.bean.Common;
@Repository(value = "res")
public class TRespository {
@Autowired(required=false)
private Common sc;
public void respon() {
System.out.println("标识持久层组件.....");
System.out.println(sc);
}
}
非注解类
package cn.com.bean;
public class Common {
public void cm() {
System.out.println("我就是一个普通的没有被注解的类的方法...");
}
}
运行结果不会报错,结果:
标识持久层组件.....
null
我只是觉得奇怪,为什么非要打印类名sc,难道不能调用sc.cm()方法么,打印出cm()方法里面的话?
事实是不能这样做,会报空指针异常!
我想加了注解@Autowired的作用就是相当于给这个属性初始化了;
而只有注解文件之间才可以相互调用方法,注解文件和非注解文件之间的方法是调不得的!尽管设置@Authwired 注解的 required 属性为 false,也仅仅是不报错而已,如果有其他的见解可以评论我!
默认情况下, 当 IOC 容器里存在多个类型兼容的 Bean 时, 通过类型的自动装配将无法工作. 此时可以在 @Qualifier 注解里提供 Bean 的名称. Spring 允许对方法的入参标注 @Qualifiter 已指定注入 Bean 的名称
这句话什么意思???
例如A类、B类都继承一个接口C,在一个注解类D中调用这个C接口类型的方法,这个时候调用就会报错,
因为匹配是唯一的;
No qualifying bean of type [cn.com.bean.controller.ControllInter] is defined: expected single matching bean but found 2: controllerClass,controllerJdbc
那么只需要在D中设置
@Qualifier("controllerJdbc")里面是bean的名称就可以了
demo如下
controllerClass,controllerJdbc都继承了ControllInter
在CompentClass里面有一个ControllInter类型的,我们都知道这个类型的类有两个,如果没有用@Qualifier("controllerJdbc")bean名称来识别的话,就会报错,
package cn.com.bean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import cn.com.bean.controller.ControllInter;
@Component
public class CompentClass {
@Autowired
@Qualifier("controllerJdbc")
private ControllInter in;
public void text(){
System.out.println("我是受Spring管理的基类....");
in.save();
}
}