目录
Spring学习的一些总结
关于@Resource(@Autowired)的使用限制
在Spring开发中,通过IoC控制反转将对象交付Spring容器管理。使用注解开发之后,用@Resource注解在很多地方都替代了new关键字的使用,原本需要new的对象直接使用@Resource自动装配。然而简单地理解为@Resoure替代了new是错误的,@Resource只是自动装配。
通过@Resource(@Autowired)注解自动装配必须在有@Component(@Service,@Controller,@Respository)或@Configuration注解的类中使用。
原因:@Component表示Spring注册了这些类,它们可以使用了,而@Resource仅仅表示由Spring自动装配这些对象,不再需要setter方法了。
关于<bean>标签中的id与name,以及Spring底层唯一标识beanName的原理
关于标签的id
与name
其中id
属性作为全局唯一,不可出现重复的名称,我们发现,之前其实就是通过Bean的名称来向IoC容器索要对应的对象,也可以通过其他方式获取。
name
属性也是bean中的属性之一,与id
属性的不同是,name
属性可以有多个值,也可以全局不唯一,重复出现。
关于Spring的底层唯一标识beanName
需要注意的是,Spring底层是通过一个名为beanName
的属性值来唯一标识每个bean的,这个beanName
可能是id
,可能是name
,也可能是其它,具体情况如下:
Spring在实例化一个bean之前,首先需要解析bean的配置,bean的配置要么通过标签(<bean>
)配置在xml文件中,要么通过注解(如@Component
,@Service
,@Bean
等)在配置类或方法上声明一个bean,确定bean的beanName
时:
- 首先看bean中有没有配置id属性,如果配置了,那么以该id作为beanName。
- 如果bean中没有配置id属性,但是配置了name属性,那么以该属性中的第一个name(name的value可以配置多个,以逗号分隔)作为beanNme。
- 如果以上两者都未配置,那么检查bean是否配置了class属性,如果配置了,以class的全路径类名作为beanName;否则检查是否设置了parent属性,如果设置了parent,则以parentName + "$child"作为beanName;否则检查是否设置了factory-bean属性,如果设置了,那么已factory-bean + “$created” 作为beanName。
- 如果bean未配置在xml文件中,而是通过注解的形式声明,那么首先检测是否配置了value属性,如果配置了,那么以该value作为beanName;否则以class名称的首字母小写作为作为beanName。
关于@Resource与@Autowired注解使用的异同
@Resource
默认byName,如果找不到则byType,可以添加到set方法、字段上。@Autowired
默认byType,如果找不到或找到多个则byName,可以添加在构造方法、set方法、字段、方法参数上。- 但是
@Autowired
可以配合@Qualifier
使用,进行指定名称的byName自动装配。
@Resource
装配场景具体如下:
@Resource有两个核心属性:name和type。
- 如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常。
- 如果指定了name,则byName(根据名称)进行装配,找不到则抛出异常。
- 如果指定了type,则byType(根据类型)进行装配,找不到或者找到多个,都会抛出异常。
- 没有任何指定(默认情况),则采用byName进行装配,如果没有匹配到,则采用byType进行匹配,如果找不到或者找到多个,则抛出异常。
@Autowired
装配场景具体如下:
@Autowired没有属性,但是可以配合@Qualifier使用。
- 如果只有@Autowired,则byType(根据类型)进行装配,如果找不到或找到多个,则采用byName进行匹配,如果找不到,则抛出异常。
- 如果配合@Autowired配合@Qualifier使用,则byName(根据名称)(此处的名称是@Qualifier所指定的名称)进行装配,如果找不到,则抛出异常。
关于@Component与@Bean的使用场景
Spring中有两种通过注解进行bean声明的方式:@Component与@Bean。
什么时候该用什么方式去声明呢?
- 如果要注册为Bean的类是由其他框架提供,我们无法修改其源代码,那么我们就使用第一种方式进行配置。
- 如果要注册为Bean的类是我们自己编写的,我们就可以直接在类上添加注解,并在配置中添加扫描。
@Resource(@Autowired)自动注入的使用方法
@Resource(@Autowired)使用接口或实现类都可以,但是更推荐接口,这样有助于降低耦合。
使用SpringAOP的切入点表达式时,execution指定的切入点
使用SpringAOP的切入点表达式时,execution指定的切入点可以是目标类方法的接口,也可以是目标类方法的实现,推荐使用接口,可以降低耦合度。
使用@Autowired注解在字段上进行自动注入时IDEA会警告
Spring5中不建议使用字段注入(Field Injection)的方式进行自动注入,IDEA会对如下情况警告:
@Controller
public class StudentController {
@Autowired
private StudetntService studentService;
}
Spring5中推荐使用构造器注入(Constructor Injection)的方式进行自动注入,具体形式如下:
@Controller
public class StudentController {
private StudentService studentService;
//Spring4之后,如果类只提供了一个带参数的构造方法,则不需要对其内部的属性写@Autowired 注解,Spring会自动为你注入属性。
@Autowired //所以,Spring4之后,此处@Autowired注解可以省略
public StudentController(StudentService studentrService) {
this.studentService = studentService;
}
}
扩展
Spring中注解自动注入的三种方法:
- 字段注入(Field Injection)
@Controller
public class StudentController {
@Autowired
private StudentService studentService;
}
- 构造器注入(Constructor Injection)
@Controller
public class StudentController {
private StudentService studentService;
@Autowired
public StudentController(StudentService studentService) {
this.studentService = studentService;
}
}
- setter方法注入(Setter Injection)
@Controller
public class StudentController {
private StudentService studentService;
@Autowired
public void setStudentService(StudentService studentService){
this.studentService = studentService;
}
}