阿华代码,不是逆风,就是我疯
你们的点赞收藏是我前进最大的动力!!
希望本文内容能够帮助到你!!
目录
引入
类注解是添加到某个类上的,但是存在两个问题
1. 使⽤外部包⾥的类,没办法添加类注解
2. ⼀个类,需要多个对象,⽐如多个数据源
这种场景,我们就需要使⽤⽅法注解 @Bean
一:@Bean方法注解
1:方法注解要搭配类注解使用
@Component
public class BeanConfig {
@Bean
public User user() {
User user = new User();
user.setName("zhangsan");
user.setAge(18);
return user;
}
}
@SpringBootApplication
public class SpringIocDemoApplication {
public static void main(String[] args) {
// 获取Spring上下⽂对象
ApplicationContext context = SpringApplication.run(SpringIocDemoApplication.class, args);
// 从Spring上下⽂中获取对象
User user = context.getBean(User.class);
// 使⽤对象
System.out.println(user);
}
}
2:执行结果
如果不搭配类注解使用,Spring会报错没有找到这样一个Bean对象
二:如何定义多个对象
我们试想一下,如果一个类中,有多个方法都被@Bean注解修饰了,那么Spring在调用的时候怎么区分,我们需要调用的是哪个方法呢,比如上面的举例,有user1方法,user2方法
1:代码示例及运行结果
main方法沿用上述的
@Component
public class BeanConfig {
@Bean
public User user1() {
User user = new User();
user.setName("zhangsan");
user.setAge(18);
return user;
}
@Bean
public User user2() {
User user = new User();
user.setName("lisi");
user.setAge(19);
return user;
}
}
报错信息显⽰:期望只有⼀个匹配,结果发现了两个,user1,user2
从报错信息中,可以看出来,@Bean注解的bean,bean的名称就是它的⽅法名
2:根据名称获取bean对象
@SpringBootApplication
public class SpringIocDemoApplication {
public static void main(String[] args) {
// 获取Spring上下⽂对象
ApplicationContext context = SpringApplication.run(SpringIocDemoApplication.class, args);
// 根据bean名称, 从Spring上下⽂中获取对象
User user1 = (User) context.getBean("user1");
User user2 = (User) context.getBean("user2");
System.out.println(user1);
System.out.println(user2);
}
}
3:重命名Bean
通过设置name属性给Bean对象进⾏重命名操作,扫描线程类SpringIocDemoApplication代码此处省略(可参考上面)
(1)代码示例
@Bean(name = {"u1","user1"})
public User user1(){
User user = new User();
user.setName("zhangsan");
user.setAge(18);
return user;
}
(2)注意点
name={}可以省略,只有⼀个名称时,{}也可以省略
三:扫描路径
思考:如果对象很多,我们实际用到的对象很少,那么Spring全都扫描一遍是不是非常浪费资源,那么扫描线程类SpringIocDemoApplication的扫描范围是如何规定的呢?
1:移动扫描线程类
我们把扫描线程类放到controller包路径下,在运行代码试试
@SpringBootApplication
public class SpringIocDemoApplication {
public static void main(String[] args) {
// 获取Spring上下⽂对象
ApplicationContext context = SpringApplication.run(SpringIocDemoApplication.class, args);
// 从Spring上下⽂中获取对象
User u1 = (User) context.getBean("u1");
// 使⽤对象
System.out.println(u1);
}
}
2:运行结果
解释:没有bean的名称为u1,因为扫描线程类此时处于controller包下,那么默认只扫描controller包路径下的类,所以没有被扫描到的类,当然就拿不到bean对象了。
3:配置扫描路径@ComponentScan({})
@ComponentScan({"com.example.demo"})
在扫描线程类上加上注解@ComponentScan({"com.example.demo"}),就可以了
(1)注意点
{}⾥可以配置多个包路径,但是实际应用并不做推荐
(2)默认扫描范围
思考:为什么前⾯没有配置@ComponentScan注解也可以呢?
@ComponentScan 注解虽然没有显式配置,但是实际上已经包含在了启动类声明注解@SpringBootApplication 中了,默认扫描的范围是SpringBoot启动类所在包及其⼦包
(3)推荐做法
把启动类放在我们希望扫描的包的路径下,这样我们定义的bean就都可以被扫描到