上一篇博客我们介绍了如何使用xml来引入bean对象,当项目多的时候,显然那样是比较麻烦的。现在我们只需要 个注解就可以替代了。注意:注解和xml可以同时使用
准备工作:配置扫描路径
我们需要配置 下存储对象的扫描包路径,只有被配置的包下的所有类,添加了注解才能被正确的识别并保存到 Spring 中。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:content="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"> <content:component-scan base-package="com.bit.service"></content:component-scan> </beans>
更方便的存储到Spring
类注解:@Controller、@Service、@Repository、@Configuration、@Component 方法注解:@Bean属性注解:@Autowired、@Resource
五大类注解
@Configuration(配置):配置层,配置当前项目的一些信息
@Controller(控制器):控制层,主要负责前端参数校验,检查用户参数的有效性
@Service(服务):服务层,调用持久化类实现相应的功能(不直接和数据库交互,类似控制中心)
@Repository(仓库):持久层,直接和数据库进行交互,通常每个表都有一个对应的Repository
@Component(组件):公共工具类,提供某些公共方法,是其他四个注解的父亲。通常不属于上面四种情况的时候使用这个,可以理解为其他。
Bean Name
这里的Bean Name 指的就是getBean方法中要传入的第一个参数 String s,注解里就相当于这个类id第二个参数是一个类
- 第一个字母大写 第二个字母小写 -----> 第一个字母变为小写
直接看源码发掘类注解Bean Name的命名规则:
方法注解
配合类注解使用,否则就是无效的注解。因为不会扫描到这个类,自然就不会扫描到这个方法。
方法注解只支持ApplicaContext,不支持BeanFactory。BeanFactory无法扫描到Bean注解,猜测是因为bean这个功能更新的晚,BeanFactory也基本不用了所以就...
Bean Name
- 默认情况 Bean name == 方法名
- 可以自定义Bean name,但是注意自定义之后,默认的就失效了.
从下面的图我们可以看到,Bean Name如果自定义的话是一个String的数组,是可以有多个命名的。
定义命名的格式有下面几种
1. @Bean("name1") 2. @Bean(name = "name1") 3. @Bean(name = {"name1","name2"})
更方便的从Spring中获取
获取 bean 对象也叫做 对象装配,是把对象取出来放到某个类中,有时候也叫 对象注入。属性注入的三种方式都是使用 @AutoWired
属性注入
其实就是 简化了获取对象的流程,直接使用注解即可。如下面代码:
假设现在服务层有一个类 @Service public class StudentService { @Bean("name1") public void sayHi(){ System.out.println("Hi,Service"); } } 而在控制层需要调用这个sayHi方法。 @Controller public class StudentController { //新方法,直接使用@Autowired获取到studentService @Autowired StudentService studentService; public void sayHi() { studentService.sayHi(); } //老方法先获取一个ApplicationContext 在调用getBean方法相对来说比较麻烦 public void sayHi2(){ ApplicationContext context = new ClassPathXmlApplicationContext("Spring-config.xml"); StudentService studentService= context.getBean("studentService",StudentService.class); studentService.sayHi(); } }
构造方法注入
@Controller public class UserController2 { // 注入方法2:构造方法注入 private UserService userService; @Autowired public UserController2(UserService userService) { this.userService = userService; } public User getUser(Integer id) { return userService.getUser(id); } }
- 注意:只有一个构造方法的时候@Autowired可以省略,如下代码
@Controller public class UserController2 { // 注入方法2:构造方法注入 private UserService userService; public UserController2(UserService userService) { this.userService = userService; } public User getUser(Integer id) { return userService.getUser(id); } }
- 注意:当有多个构造方法的时候必须有@Autowired 来明确指定到底使用哪个构造方法,否则会报错
Setter注入
Setter 注入和属性的 Setter 方法实现类似,只不过在设置 set 方法的时候需要加上 @Autowired 注解,如下面代码
Setter注入 Setter 注入和属性的 Setter 方法实现类似,只不过在设置 set 方法的时候需要加上 @Autowired 注解,如下面代码
三种注入方法比较
属性注入的优点是简洁,使用方便;缺点是只能用于 IoC 容器,如果是非 IoC 容器不可用,并且只有在使用的时候才会出现 NPE(空指针异常)。
构造方法注入是 Spring 推荐的注入方式,它的缺点是如果有多个注入会显得比较臃肿,但出现这种情况,你应该考虑一下当前类是否符合程序的单一职责的设计模式了,它的优点是通用性,在使用之前一定能把保证注入的类不为空。
Setter 方式是 Spring 前期版本推荐的注入方式,但通用性不如构造方法,所有 Spring 现版本已经推荐使用构造方法注入的方式来进行类注入了。
@Resource:另一种注入关键字
@Autowired 和 @Resource 的区别:
出身不同:@Autowired 来自于 Spring,而 @Resource 来自于 JDK 的注解;
使用时设置的参数不同:相比于 @Autowired 来说,@Resource 支持更多的参数设置,例如name 设置,根据名称获取 Bean。
@Autowired 可用于 Setter 注入、构造函数注入和属性注入, @Resource 不能用于构造函数入
多个 Bean 报错处理
①使用更精准的Bean名称
@Controller public class UserController5 { // 注入 @Autowired private User user1; public User getUser() { return user; } }
① 使用 @Resource(name="XXX")
@Controller class UserController4 { // 注入 @Resource(name = "user1") private User user; public User getUser() { return user; } }
② 使用 @Qualifier
@Controller public class UserController5 { // 注入 @Autowired @Qualifier(value = "user2") private User user; public User getUser() { return user; } }
总结
1. 将对象存储到 Spring 中:
使用类注解:@Controller、@Service、@Repository、@Configuration、@Component【它们之间的关系】
使用方法注解:@Bean【注意事项:必须配合类注解一起使用】
2. Bean 的命名规则:
首字母和第二个字母都非大写,首字母小写来获取 Bean,如果首字母和第二个字母都是大写,那么直接使用原 Bean 名来获取 Bean。
3. 从 Spring 中获取对象:
属性注入
Setter 注入
构造函数注入(推荐)
4. 注入的关键字有:
@Autowired
@Resource
5. @Autowired 和 @Resource 区别:
出身不同;
使用时设置参数不同
@Resource 支持更多的参数,比如 name。
6. 解决同一类型多个 Bean 的报错:
使用 @Resource(name="")
使用 @Qualifier("")