提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
- @Bean
- 一、如何使用方法注解
- 注意Bean 的命名规则,==当没有设置 name 属性时,那么 bean 默认的名称就是方法名==,
- 当设置了 name 属性之后,只能通过==重命名的name 属性对应的值来获取==,也就是说重命名之后,再使用方法名就获取不到 bean 对象;
- 二、同一类型的对象注入多次的问题
- 1、精准的描述bean的名称(将注入的名称写对)
- 2、使用@Resource设置name的方式来重命名注入的对象;
- 3、使用@AutoWired+@Qualifier来筛选bean对象;
- 对象注入的三种方法
- 1、属性注入
- 2、构造方法注入
- 3、Setter方法注入
- 4. 属性注入和构造方法注入以及 Setter 注入的区别是什么?
@Bean
一、如何使用方法注解
1、类注解是写到类上面的,那么方法注解是写到对应的方法上的;
@Bean(name = "user1")
public User getUser1() {
User user = new User();
user.setId(1);
user.setName("张三");
return user;
}
2、方法注解的话是不能够单独使用的,如果我们只给一个方法注解@Bean的话,看是否能运行;
ApplicationContext context= new ClassPathXmlApplicationContext("spring-config.xml");
User user = context.getBean(User.class);//只使用类属性
System.out.println(user);
运行结果:
如何解决?我们只需要在方法注解的类中添加一个类注解即可;
再次运行:
注意Bean 的命名规则,当没有设置 name 属性时,那么 bean 默认的名称就是方法名,
当设置了 name 属性之后,只能通过重命名的name 属性对应的值来获取,也就是说重命名之后,再使用方法名就获取不到 bean 对象;
比如已经给bean重命名了,我们在启动类App中通过方法名来获取Bean对象;
看运行结果:
二、同一类型的对象注入多次的问题
1、在UserBeans类中写两个对象注解;
@Component
public class UserBeans {
@Bean(name = "user1") // 【注意事项:只使用一个 @Bean 是无法将对象存储到容器中的】
public User getUser1() {
User user = new User();
user.setId(1);
user.setName("张三");
return user;
}
@Bean(name = "user2") // 【注意事项:只使用一个 @Bean 是无法将对象存储到容器中的】
public User getUser2() {
User user = new User();
user.setId(2);
user.setName("李四");
return user;
}
2、通过启动类来获取对象;
ApplicationContext context= new ClassPathXmlApplicationContext("spring-config.xml");
User user = context.getBean(User.class);//只使用类属性
System.out.println(user);
翻译过来的意思就是:没有可用的“com.User”类型的合格bean:应为单个匹配bean,但找到2:user1,user2;
那么,如何解决呢?这里我们提供了三种解决方案;
1、精准的描述bean的名称(将注入的名称写对)
比如我们在启动类中使用id+class的形式来取对象;
ApplicationContext context= new ClassPathXmlApplicationContext("spring-config.xml");
User user = context.getBean("user1",User.class);//只使用类属性
System.out.println(user);
2、使用@Resource设置name的方式来重命名注入的对象;
1、这里我们通过UserController类来进行演示;注意我们添加的注解@Resource,下面新写了一个对象user1;
package com;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Controller;
import javax.annotation.Resource;
@Controller
public class UserController {
@Resource
private User user1;
public void sayHi(){
System.out.println("User"+user1);
}
}
启动类App中代码:
ApplicationContext context= new ClassPathXmlApplicationContext("spring-config.xml");
UserController userController = context.getBean(UserController.class);
userController.sayHi();
3、使用@AutoWired+@Qualifier来筛选bean对象;
UserController代码:
package com;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Controller;
import javax.annotation.Resource;
@Controller
public class UserController {
@Autowired
@Qualifier(value = "user2")
private User user2;
public void sayHi(){
System.out.println("User"+user2);
}
}
对象注入的三种方法
1、属性注入
属性注⼊是使⽤ @Autowired 实现的,将 Service 类注⼊到 Controller 类中。
package com;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import javax.annotation.Resource;
/**
* 根据属性实现 bean 对象的注入
*/
@Controller
public class UserController2 {
// 对象注入方式1:属性注入
@Autowired
private UserService userService;
public void sayHi() {
userService.sayHi();
}
}
启动类App:
ApplicationContext context= new ClassPathXmlApplicationContext("spring-config.xml");
UserController2 userController2 = context.getBean(UserController2.class);
userController2.sayHi();
2、构造方法注入
package com;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
/**
* 使用构造方法实现 bean 注入
*/
@Controller
public class UserController3 {
private UserService userService;
// 构造方法注入(官广推荐写法)
@Autowired
public UserController3(UserService userService) {
// userService = new UserService(); // 传统的写法
this.userService = userService;
}
public void sayHi() {
userService.sayHi();
}
}
注:如果当前类只存在一个构造方法,那么@Autowired注解可以省略;
启动类App:
ApplicationContext context= new ClassPathXmlApplicationContext("spring-config.xml");
UserController3 userController3 = context.getBean(UserController3.class);
userController3.sayHi();
3、Setter方法注入
package com;
import org.springframework.stereotype.Controller;
import javax.annotation.Resource;
/**
* 使用 Setter 实现 bean 注入
*/
@Controller
public class UserController4 {
private UserService userService;
@Resource
public void setUserService(UserService userService) {
this.userService = userService;
}
public void sayHi() {
userService.sayHi();
}
}
启动类App:
ApplicationContext context= new ClassPathXmlApplicationContext("spring-config.xml");
UserController4 userController4 = context.getBean(UserController4.class);
userController4.sayHi();
4. 属性注入和构造方法注入以及 Setter 注入的区别是什么?
- 属性注入:特点写法简单。但是通用性不好,它只能运行在 IoC 容器下,如果是非 IOC 容器就会出现问题。
- Setter 注入:早期 Spring 版本推荐的写法,Setter 注入通用性没有构造方法注入通用。
- 构造方法注入: 通用性更好、它能确保在使用注入对象之前,此注入对象一定初始化过了。当构造方法注入参数过多时,此时开发者就要检查自己所写的代码是否符合单一设计原则的规范了,此注入方式也是 spring后期版本中推荐的注入方式。