目录
1.直接调用context.getBean(...),其实使用频率不高,(了解即可)
2.使用bean 注入的方式使用(Ioc/DI体现的地方)被广泛使用
1.作为卖方如何进行注册
(1)直接将对象的创建过程委托给spring容器
(2)将一个已经创建好的对象注册
a 通过静态方法(工厂方法:生产对象的一种方法)
通过这个类的下的createPerson这个方法,就可以得到一个对象,这个对象的名字叫 通过工厂注册。
b.通过实例方法
通过bean注册进来的一个对象,然后传入一个对象,和方法名
key是id,value是任意类型的对象。
买方通过getBean和依赖注入的方式获取bean
逻辑上作为买方是注册bean的方式,有两种
2. spring怎么实例化对象
逻辑上作为卖方是注册bean的方式,有两种
1.告诉Spring容器哪个类,实例化过程让Sping完成
2.告诉Spring容器一个方法,实例化过程是我们自己的代码写的
而Spring是通过java反射机制来做到这一点的
买方使用时也是两种方式
1.直接获取 context.getBean(...)
2.使用注入的方式(这种方式既是卖方也是买方)(要求,被注入的类的实例化过程是spring处理的)
注入方法:通过构造方法注入
通过setter方法注入
3.通过注解的方式进行bean的注册
有了注解,spring进行扫描就知道,这个要被我管理
4.新建项目专门学习注解的方式
在ioca这个包下面的都可以扫描到,不在这个包下面的扫描不到 ,写在别的包用注解修饰没有意义
(1)注解方式注册的必要条件
(2)要在 XXXApplication 所在的包下面
会多出来一个bean
代码如果写为private,也还是可以注册bean,但是还是写public
1.@Component 是用来修饰类的,被注解修饰的类,全部注册进Spring容器中
而其实例化的过程也完全交给Spring。
没有特别的场景,都可以用@Component
@Controller public class Hello { public Hello() { System.out.println("Hello() 被调用"); } }
总结:要记住,在idea配置中写出来
2.直接将对象注册到Spring中的注解
![]()
结果会多了两个bean![]()
@Configuration public class AppConfig { @Bean("王淇") //它的名字叫 王淇 public String wangqi(){ return "王小熊"; } }
5.获取bean的方式
1.直接调用context.getBean(...),其实使用频率不高,(了解即可)
根据id获取
根据类型获取
id 和类型都指定也可以
2.使用bean 注入的方式使用(Ioc/DI体现的地方)被广泛使用
// 需要用到 Hello 类,所以这个类必须有 // 1. 先让 Person 类被注册进 Spring 容器,并且,实例化过程委托给 Spring。—— @Component 修饰 Person 类 :对象的卖方(卖 Person 对象) // 2. 要求 Hello 类已经被注册到 Spring 容器中了(类注册 or 方法注册都可以):对象的买方(买 Hello 对象) // 2.1. 直接使用构造方法注入 @Component public class Person { @Autowired // 这个注解其实可以不写,但建议写上,主要是让看代码的人,知道我们的 Hello 对象是被注入的 // 如果有多个构造方法,告诉 Spring,实例化 Person 对象时,应该调用哪个 public Person(Hello hello) { System.out.println("Person(), hello = " + hello); } public Person(int x) { System.out.println("Person()"); } }
意思是person类需要被管,Hello要之前就有
setter方法的注入,必须带注解
// 需要用到 Hello 类 // 1. 先让 Person 类被注册进 Spring 容器,并且,实例化过程委托给 Spring。—— @Component 修饰 Person 类 :对象的卖方(卖 Person 对象) // 2. 要求 Hello 类已经被注册到 Spring 容器中了(类注册 or 方法注册都可以):对象的买方(买 Hello 对象) // 2.2. 使用 setter 方法去注入 @Component public class Person2 { public Person2() { System.out.println("Person2() 被调用"); } @Autowired // 必须带上 public void setHello(Hello hello) { System.out.println("setHello(), hello = " + hello); } }
属性直接注入
// 需要用到 Hello 类 // 1. 先让 Person 类被注册进 Spring 容器,并且,实例化过程委托给 Spring。—— @Component 修饰 Person 类 :对象的卖方(卖 Person 对象) // 2. 要求 Hello 类已经被注册到 Spring 容器中了(类注册 or 方法注册都可以):对象的买方(买 Hello 对象) // 2.2. 使用属性直接注入 @Component public class Person3 { @Autowired // hello 属性的值会被 Spring 容器对象注入 private Hello hello; // 通过反射方式,即使是 private,也可以绕开访问限制 public Person3() { System.out.println("Person2() 被调用"); } public void printHello() { System.out.println("printHello(), hello = " + this.hello); //这里没有赋值,但是值会被注入进来 } }
定义的属性没有赋值,但是自己就有
坑点:属性注入要注意顺序(很危险,建议不要使用)
// setter 注入 / 属性直接注入上 @Component public class 注入时的一个坑 { @Autowired // 进行了属性注入 private Hello hello; public 注入时的一个坑() { // 不是注入了么,为什么 hello 还是 null 呢,为什么没有注入成功? // 因为构造方法先执行,然后进行注入(属性注入/setter注入) // 所以,构造方法执行的时候,注入还没有发生,所以还是 null // 这也是为什么建议使用构造方法注入 System.out.println("注入时的一个坑(), hello = " + this.hello); // 这里的 hello 打印什么? null 还是 非null } }
也可以配合bean来注入,是一种方法注入
@Bean // 这里的 Hello hello 由 Spirng 注入 // 因为 createPerson 被 Spring 调用,它可以填写我们指定的需要的参数 public Person createPerson(@Autowired Hello hello) { System.out.println("createPerson(), hello = " + hello); return new Person(hello); }
总结:
是收手动完成的,调用spring是不行的
每个bean只会有一份,都是单例的