
@Bean@Bean 告诉 spring,这个方法返回的对象要放进 IoC 容器(ApplicationContext)里,成为可被任何其他 Bean 注入的组件。
💥注意事项:
@Bean 要配合五大注解使用,不能单独使用Spring 中,默认情况下 Bean 的作用域是 singleton(单例)的,即整个 Spring 容器中只存在一个该 Bean 实例。Bean 对象的话,需要对不同的方法进行注解,然后使用 ApplicationContext 对象的 getBean() 方法中传入 Bean 名称的方式进行获取,对应的 Bean 名称是对应方法的名称,当然也可以进行重命名,默认重命名的属性是 name,如下所示:@Component
public class UserComponent {
@Bean("{u3}")
public User u1() {
return new User();
}
@Bean
public User u2() {
return new User();
}
}
public static void main(String[] args) {
ApplicationContext context = SpringApplication.run(Application.class, args);
// 通过 Bean 名获取,不然 Spring 会报错,识别不出要哪个对象
// 并且可以对 Bean 对象进行重命名!
User u1 = (User)context.getBean("u3");
User u2 = (User)context.getBean("u2");
System.out.println(u1);
System.out.println(u2);
}
// 运行结果:
com.liren.ioc.model.User@abbe000
com.liren.ioc.model.User@3f81621c@ComponentScanSpring 默认扫描的范围是 SpringBoot 启动类所在包及其子包,如下图所示,一般也推荐直接把启动类放到项目目录中!

但是如果需要放在特定包内,还需要访问其它非子包的包内,则需要使用 @ComponentScan 来添加要扫描的包,如下所示,当然也可以用 {} 配置多个包路径!
@ComponentScan("com.liren.ioc.service") // 指定扫描com.liren.ioc.service包中的内容
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}@Autowired这种方式虽然不是官方最推荐的,但却是日常开发最常用的。
@Controller
public class UserController {
@Autowired
private UserService userService;
public void func() {
System.out.println("UserController");
userService.func();
}
}💥注意:如果类只有一个构造方法,那么 @Autowired 注解可以省略;如果类中有多个构造方法,那么需要添加上 @Autowired 来明确指定到底使用哪个构造方法。
@Controller
public class UserController {
private UserService userService;
// 默认构造方法
public UserController() {}
// 如果有默认构造方法,那么不显式写上@Autowired的话,会去调用默认构造方法
@Autowired
public UserController(UserService userService) {
this.userService = userService;
}
public void func() {
System.out.println("UserController");
userService.func();
}
}Setter方法注入@Controller
public class UserController {
private UserService userService;
@Autowired
public void setUserService(UserService userService) {
this.userService = userService;
}
public void func() {
System.out.println("UserController");
userService.func();
}
}IOC 容器,如果是非 IOC 容器不可用,并且只有在使用的时候才会出现空指针异常Final 修饰的属性final 修饰的属性JDK 支持的,所以更换任何框架,它都是适用的3. Setter 注入(Spring 3.X 推荐)
final 修饰的属性setter 方法可能会被多次调用,就有被修改的风险@Autowired 存在的问题当同一个类存在多个 Bean 时,使用 @Autowired 会存在问题,如下所示:

如何解决上述问题呢❓❓❓Spring 提供了以下几种解决方案:
@Primary@Qualifier@Resource@Primary当存在多个相同类型的 Bean 注入时,加上 @Primary 注解,来确定默认的实现!
这个注解加在要被指定注入的 Bean 对象上,如下所示:
@Component
public class UserComponent {
@Primary
@Bean
public User u3() {
return new User();
}
@Bean
public User u4() {
return new User();
}
}@Qualifier注意该注解不能单独使用,需要配合 @Autowired 才行!
@Controller
public class UserController2 {
@Qualifier("u3") // 指定对应Bean的名称
@Autowired
private User user;
public void func() {
System.out.println("UserController2");
}
}@Resource⭐⭐⭐该注解可以单独使用,不过需要显式用属性 name 来指定对应的 Bean 对象!
@Controller
public class UserController2 {
@Resource(name = "u3") // 需要显式写一下name来指定
private User user;
public void func() {
System.out.println("UserController2");
}
}需要注意的是,@Resource 是 JDK 自带的,支持更多的参数设置,而 @Autowired 是 Spring 框架提供的,没有前者功能那么多!
@Autowired 的装配顺序如下图所示:

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。