@Autowired
@Autowired是用在JavaBean中的注解,通过byType形式,用来给指定的字段或方法注入所需的外部资源
原理:
在启动spring IoC时,容器自动装载了一个AutowiredAnnotationBeanPostProcessor后置处理器,当容器扫描到@Autowied、@Resource(是CommonAnnotationBeanPostProcessor后置处理器处理的)或@Inject时,就会在IoC容器自动查找需要的bean,并装配给该对象的属性
我通俗的理解为:@Autowired是一个自动装配的工具,当这个注解加在某个变量上时,系统自动的去容器里找这个类型的对象,如果容器里只有一个,那个就把容器里的对象注入到该注解指定的变量的位置上(赋值);如果容器里,这个类型的对象多于一个,则按ByName方式查找;如果容器里没有这个对象,那么会抛出异常。解决方法时,使用required=false
作用:
@Autowired有什么作用呢 作为spring核心思想IOC的核心注解,我认为他的主要作用就是引入容器里已有的对象的值(它比new好的一点就是,new是创建新的,@Autowired是拿现有的,所以@Autowired能做到数据共享,而new不行)
spring是一个容器,这个容器里面有各种各样的对象,当人们想用容器里的对象时,去容器里拿现有的对象直接用。
那么什么时候能体现@Autowired的方便性呢?
当一个类的变量要被多个类使用时,且该变量的内容被多个类共享时,这个时候我们的解决办法就是:把这个要被多次使用且数据共享的类放到spring容器中,由spring容器管理它,我们使用@Autowired引入容器里的类
举个例子:
要求实现一个项目要在指定时间发布出去。方案:我首先想到的就是spring的定时任务,那么实现起来的话,我分为任务类(要做什么),任务管理类(任务调度器,添加任务,移除任务),service
在这个例子是怎么体现数据共享的呢?我们往下看 任务管理类中有一个Map存储正在运行的任务(可以理解为线程池的显示) 那我们发布完项目,这个任务应该结束掉(在线程池中移除),所以,我们需要在执行完任务,就把该任务从线程池中移除,那么就是在任务类中引入任务管理类,并做到共享线程池(map) 做法:在任务管理类上加@Component把它放到spring容器中,再任务类中某变量上加入@Autowired引入容器中的对象。
注:@Autowired和构造方法
Java变量的初始化顺序为:静态变量或静态语句块–>实例变量或初始化语句块–>构造方法
声明:构造方法是在@Autowired前执行。
eg:
@Autowired写在构造方法外,他的实际值为null
public class TaskRunnable implements Runnable {
private String name;
@Autowired
private TaskManager taskManager;
public TaskRunnable(String name) {
this.name = name;
}
}
这么写才是正确的,当该类有有参构造时,@Autowired要加在构造方法上能引入容器中的对象
public class TaskRunnable implements Runnable {
private String name;
private TaskManager taskManager;
@Autowired
public TaskRunnable(String name,TaskManager taskManager) {
this.name = name;
this.taskManager=taskManager;
}
}