闲聊:Setter 注入是 Spring 3.X 推荐的,构造方法注入是 Spring 4.X 推荐的,而咱们程序员呢,就推荐 属性注入,因为简单~~
当同一类型存在多个 bean 时, 使用@Autowired会存在问题
我们先用一个对象试试👇
UserService.java👇
java复制代码
@Service//此时也是交给Spring管理了
public class UserService {
@Autowired
private Student s1;
public void print(){
System.out.println("do Service");
System.out.println(s1);
}
}
StudentComponrnt.java👇
java复制代码
@Component
public class StudentComponent {
@Bean({"s3","s4"})
public Student s1(){
return new Student("CoderYanger",21);
}
@Bean
public String name(){
return "Ayanger";
}
// @Bean
// public Student s2(String name){
// return new Student(name,12);
// }
}
启动类👇
java复制代码
@SpringBootApplication
public class SpringIocDemoApplication {
public static void main(String[] args) {
//获取Spring上下文对象,直接使用父类接收
ApplicationContext context = SpringApplication.run(SpringIocDemoApplication.class, args);
//从Spring容器中拿到UserService,并调用它的方法
UserService bean=context.getBean(UserService.class);
bean.print();
}
}
@Component
public class StudentComponent {
@Bean({"s3","s4"})
public Student s1(){
return new Student("CoderYanger",21);
}
@Bean
public String name(){
return "Ayanger";
}
@Bean
public Student s2(String name){
return new Student(name,12);
}
}
@Component
public class StudentComponent {
@Bean({"s3","s4"})
public Student s1(){
return new Student("CoderYanger",21);
}
@Bean
public String name(){
return "Ayanger";
}
@Primary
@Bean
public Student s2(String name){
return new Student(name,12);
}
}
发现默认就使用第二个对象了👇
加在第一个对象上面👇
java复制代码
@Component
public class StudentComponent {
@Primary
@Bean({"s3","s4"})
public Student s1(){
return new Student("CoderYanger",21);
}
@Bean
public String name(){
return "Ayanger";
}
// @Primary
@Bean
public Student s2(String name){
return new Student(name,12);
}
}
此时默认就使用第一个对象了👇
方式二:@Qualifier
第一种用法:加在属性上
使用 @Qualifier 注解:指定当前要注入的 bean 对象。 在@Qualifier的 value 属性中,指定注入的 bean 的名称
Spring 有个解决问题的特点:一个注解搞不定,就两个注解搞定,两个注解还搞不定,就三个注解搞定......所以此处用 @Qualifier 去指定它的名称。因为它的源码里有 value👇
• @Qualifier注解不能单独使用,必须配合@Autowired使用
java复制代码
@Service//此时也是交给Spring管理了
public class UserService {
@Qualifier("s3")//指定bean名称为s3
@Autowired
private Student s1;
public void print(){
System.out.println("do Service");
System.out.println(s1);
}
}
此时启动服务后拿到的就是 s3 的对象👇
当我们改成 s2 时👇
java复制代码
@Service//此时也是交给Spring管理了
public class UserService {
@Qualifier("s2")//指定bean名称为s2
@Autowired
private Student s1;
public void print(){
System.out.println("do Service");
System.out.println(s1);
}
}
此时拿到的对象就是 s2👇
第二种用法:加在参数上
看完 方式三:@Resource 再来看这一条~~
@Qualifier 源码中写了可以加在参数上👇
此时代码👇
java复制代码
@Service//此时也是交给Spring管理了
public class UserService {
@Resource(name="s2")
private Student s1;
public void print(){
System.out.println("do Service");
System.out.println(s1);
}
}
@Resource 用到了 s2,s2 在这里用到了 String n,但是 n 上面有 name 和 name2 两个,应该用哪个??👇
java复制代码
@Component
public class StudentComponent {
@Primary
@Bean({"s3","s4"})
public Student s1(){
return new Student("CoderYanger",21);
}
@Bean
public String name(){
return "Ayanger";
}
@Bean
public String name2(){
return "Ayanger2";
}
@Bean
public Student s2(String n){
return new Student(n,12);
}
}
运行后发现报错,s2 需要一个单例,但是却发现两个👇
此时就可以用 @Qualifier 去指定名称,比如 name2👇
java复制代码
@Component
public class StudentComponent {
@Primary
@Bean({"s3","s4"})
public Student s1(){
return new Student("CoderYanger",21);
}
@Bean
public String name(){
return "Ayanger";
}
@Bean
public String name2(){
return "Ayanger2";
}
@Bean
public Student s2(@Qualifier("name2") String n){
return new Student(n,12);
}
}
此时拿到的就是 name2 对应的对象👇
当然,改成 name 后就是拿到的 name 对应的对象~~
方式三:@Resource
上面两个都是 Spring 的注解,都是 @Autowired 的解决方式,是根据类型的,我们没办法去指定名称,而 @Resource 却是来自 JDK👇
java复制代码
import jakarta.annotation.Resource;
闲聊:Java EE 在 2018 年的时候就更名为 jakarta EE 了,在 JDK 8 的时候这个注解就是在 JDK 里面的,在 2017 年的时候就把 Java EE 捐给 eclipse 了,然后 eclipse 就要求他使用 Java 这个名字,所以这时候关于 Java EE 的部分就拆出来了,然后就放在 Jakarta 里面了,所以虽然是拆出来了,但是我们还是倾向于认为它还是 JDK 提供的东西
我们的注解也不是说 Spring 才有的,这并不是什么很新鲜的事情,JDK 中就存在很多注解👇
以上就都是 JDK 提供的,准确而言是 Jakarta 提供的~~
使用@Resource注解:是按照 bean 的名称进行注入。通过 name 属性指定要注入的 bean 的名称
java复制代码
@Service//此时也是交给Spring管理了
public class UserService {
@Resource(name="s3")
private Student s1;
public void print(){
System.out.println("do Service");
System.out.println(s1);
}
}
我们此时发现打印的就是 s3 的对象👇
当我们把名称改为 s2 之后👇
java复制代码
@Service//此时也是交给Spring管理了
public class UserService {
@Resource(name="s2")
private Student s1;
public void print(){
System.out.println("do Service");
System.out.println(s1);
}
}
@Component
public class StudentComponent {
@Bean({"s3","s4"})
public Student s1(){
return new Student("CoderYanger",21);
}
@Bean
public String name(){
return "Ayanger";
}
@Bean
public String name2(){
return "Ayanger2";
}
@Bean
public Student s2(@Qualifier("name2") String n){
return new Student(n,12);
}
}
java复制代码
@SpringBootApplication
//加上这个注解之后,不管这个类名叫什么,它都是一个启动类
public class SpringIocDemoApplication {
public static void main(String[] args) {
//获取Spring上下文对象,直接使用父类接收
ApplicationContext context = SpringApplication.run(SpringIocDemoApplication.class, args);
//从Spring容器中拿到UserService,并调用它的方法
UserService bean=context.getBean(UserService.class);
bean.print();
}
}
当名称为 s1 时👇
java复制代码
@Service//此时也是交给Spring管理了
public class UserService {
@Autowired
private Student s1;
public void print(){
System.out.println("do Service");
System.out.println(s1);
}
}
发现报错了,只需要一个,但是找到了两个👇
我们前面说过,这个名称无所谓,叫啥都行,那么我们接下来改成 s2👇
java复制代码
@Service//此时也是交给Spring管理了
public class UserService {
@Autowired
private Student s2;
public void print(){
System.out.println("do Service");
System.out.println(s2);
}
}
我们发现它又不报错了,找到了👇
难道名称是有效的吗??再改成 s3👇
java复制代码
@Service//此时也是交给Spring管理了
public class UserService {
@Autowired
private Student s3;
public void print(){
System.out.println("do Service");
System.out.println(s3);
}
}
我们发现名称确实是有效的👇
这就是这句话不严谨的原因~~
相比于 @Autowired 来说,@Resource 支持更多的参数设置,例如 name 设置,根据名称获取 Bean.
所以 IoC 和 DI 都是 Spring 提供的功能,对对象管理,而上面的这些就是 SpringBoot 相关的👇
SpringBoot 主要是基于 Spring 给我们进行一些二次开发,就像上次说的 12306 一样
Spring:类似于火车、高铁
Spring Boot:类似于 12306,基于火车的基础上提供一些功能,不局限于火车~~
比如已经帮我们集成了 tomcat,这就不需要我们自己安装了
Spring MVC:类似火车站,火车票代售点,提供一些对外访问的功能,比如像 RequestMapping,就来自于 SpringMVC👇
Spring MVC: Spring MVC是Spring的一个子框架, Spring诞生之后, 大家觉得很好用, 于是按照MVC 模式设计了一个 MVC框架(一些用Spring 解耦的组件), 主要用于开发WEB应用和网络接口,所以,Spring MVC 是一个Web框架.
Spring MVC基于Spring进行开发的, 天生的与Spring框架集成. 可以让我们更简洁的进行Web层开发, 支持灵活的 URL 到页面控制器的映射, 提供了强大的约定大于配置的契约式编程支持, 非常容易与其他视图框架集成,如 Velocity、FreeMarker等
Spring Boot: Spring Boot是对Spring的一个封装, 为了简化Spring应用的开发而出现的,中小型企业,没有成本研究自己的框架, 使用Spring Boot 可以更加快速的搭建框架, 降级开发成本, 让开发人员更加专注于Spring应用的开发,而无需过多关注XML的配置和一些底层的实现.