目录
一、类注解是什么
二、使用类注解 存取 Bean 对象
1. 准备工作
2. 所以使用五大类注解的规则:
三、五大类注解之间的关系
1. 首先可以查看 类注解的源码如下图:
2. 为什么需要五个类注解?
3. 为什么使用类注解的方式不能使用原类名(上面的特例除外)
4. Bean的命名的规则:
四、使用 @Bean 方法注解存储对象
1. @Bean 方法注解的使用
2. @Bean 方法注解的重命名
前言
上一篇文章中,已经介绍了在 Spring 容器中如何存储和获取 Bean 对象,但是对于 Spring中对象的获取还是有更简单的方式的,先回顾上一篇的内容,获取 Bean 对象的三种方式是:
1. 通过 Bean 名称获取对象 | Student student = (Student) context.getBean("student");//根据名称获取 |
2. 通过 Bean 对象的类型获取对象 | Student student = context.getBean(Student.class);//根据类型获取 |
3. 通过 Bean 的名称 + 类型获取对象 | Student student = context.getBean("student",Student.class);//根据名称 + 类型获取 |
此种写法其实是比 new 对象还要麻烦一点的,所以就有了更简单存取 Bean 对象的方式:通过加 类注解。
一、类注解是什么
五大 类注解:(注:不是五大类 注解, 而是五大 类注解)
@Controller | 控制器:验证用户请求的数据的正确性(将非法用户拦截在程序之外) |
@Service | 服务:安排和调度具体的执行的方法,(类似机场的客服中心,给游客指明目的地,只是引导作用)Service层也是一样,不会实际操作数据库,只是用户实现一个功能需要调用哪些接口,只是帮用户调用了这个接口 |
@Repository | 持久层:和数据库交互,例如添加一个用户的操作需要执行两个Insert,UserInsert和日志中的Insert,此时在Service层会调用两个 Repository,UserRepository 和 logRepository(Repository就是最后的执行者) |
@Component | 组件(放工具类),上述几个注解都是和业务相关的,但是Component 和 业务没有什么关联,例如:在Component放一个加密的goon工具类,此时不管是什么业务,都可以使用这个工具来实现某种功能 |
@Configuration | 配置:放一些项目中的配置文件 |
二、使用类注解 存取 Bean 对象
1. 准备工作
注:如果要把 Bean 对象存到 Spring 中,就需要配置 Bean 对象的扫描路径,只有配置了,此时被配置的这个包中的所有类才可以在添加了 类注解 之后 被保存到 Spring 容器中。
这个配置的路径是否可以不设置?
其实在 Spring 实现的角度也是可以的,但是需要配置就一定是有道理的,如果不配置,此时如果加了 类注解 之后 Spring 就要去扫描 整个项目 哪些 Bean 对象 加了类注解,但是如果配置了这个扫描路径,此时在运行 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.spring.demo"></content:component-scan>
</beans>
将上述配置信息复制到spring-config.xml 文件中,然后 将 base-package (包的根路径)设置好自己的扫描路径即可。 如下图中:
在指定的配置路径下,创建一个 Bean 对象(StudentController类)
package com.spring.demo;
import org.springframework.stereotype.Controller;
@Controller //将当前类存储到 Spring 容器中
public class StudentController {
public void sayHi() {
System.out.println("do studentController sayHi()");
}
}
在启动类中获取 Bean 对象(使用类名 + 类型的方式)
注:类名不是原来的类名了,是类名(小驼峰)的形式来获取 StudentController 对象(这涉及到Spring中源码的规则,下面会详细的介绍)
特例:如果原类名首字母和第二个字母都是大写,此时就用原类名的方式来获取 Bean 对象即可。
此时可以看到用加类注解的方式也是可以获取到 Bean 对象的,不仅仅是加 @Controller,加上其他的类注解也是一样的可以获取 Bean 对象。
2. 所以使用五大类注解的规则:
1. <Bean>标签(在配置文件中写的那个)是可以和component-san一起使用的 |
2. 五注解不可以不在compent-scan中(这个也很好理解,配置五大注解才可以是使用更加方便的方式来进行获取Bean对象,spring是要保证性能的,不配置就是性能低,配置使用注解的依赖之后才可以使用注解) |
3. 即使在component-scan下,但是如果没有加五大注解,一样是不能将当前对象存储到Spring容器中的 |
4. 在component-scan下的所有子包下的类只要加了五大注解,同样能存储到Spring中。 |
5. 在扫描路径下的 不同包下的 同名的类 必须要设置别名才能存储到 Spring容器中。 |
三、五大类注解之间的关系
1. 首先可以查看 类注解的源码如下图:
如上图所示:五大类注解汇中都是基于 @Component 来实现的,说明他们是 ”@Component” 的 “子类”, 都是对 @Component 的一个扩展和升级。
2. 为什么需要五个类注解?
如上图所示:JavaEE阶段的标准分层至少分为3层,在企业中一般都是基于这3层再进行细化和扩展的。
五大类注解就是基于标准分层来创建的,五大类注解在功能层面上没有很大的差别,但是在项目中的作用每个类注解都是同等重要的:起到了标识的作用,例如:在一个程序中看到了 @Controller 就了解了当前类就是用来做前端提交过来的数据的监控的,当看到一个类上有一个 @ Repository 时就知道当前类就是直接和数据库进行交互的,此时让程序猿读代码的时候能够清晰的见名知意,清除的知道当前类的作用。
所以剩下的两个类注解 @Component 和 @Configuration 是对EE标准三层分层的补充,有的项目中可能会没有使用到这两个注解,但是如果有项目需要使用工具类和配置文件,此时就需要在标准分层之外进行额外的扩展。
3. 为什么使用类注解的方式不能使用原类名(上面的特例除外)
此时就涉及到Spring的源码了,双击 shift 打开全局搜索,搜索 BeanName,就有了下图中的类和类方法命名的方法:
综上所述源码的解释,
4. Bean的命名的规则:
1. 默认情况下是首字母小写。 |
2. 如果类名首字母和第二个字母都为大写的情况下,Bean名称为原类名。 |
验证上述源码中的方法:
如上图所示;可以看到上述代码运行结果是符合上述两个规则的。
四、使用 @Bean 方法注解存储对象
1. @Bean 方法注解的使用
注:
1. @Bean 是方法的注解,只能加在方法的上边,是不能加在类上的。 |
2. @Bean 注解必须和五大 类注解配合使用才可以生效。 |
先创建一个两个包,component 和 entity,分别在两个包中创建两个类,UserBeans 类 和 User 实体类,UserBeans 就代表了 Bean对象,User实体类就是传输数据的一个载体,完成如下代码:
package com.spring.demo.component;
import com.spring.demo.entity.User;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
@Component
public class UserBeans {
@Bean
public User user222() {
User user = new User();
user.setUid(1);
user.setUsername("张三");
user.setPassword("123456");
user.setAge(18);
return user;
}
}
package com.spring.demo.entity;
public class User {
private Integer uid;
private String username;
private String password;
private Integer age;
//...
public Integer getUid() {
return uid;
}
public void setUid(Integer uid) {
this.uid = uid;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
注:使用@Bean 方法注解之后在 getBean() 获取对象的时候,命名规则和使用五大类注解的方式不一样,方法注解,类名称就是方法的名称。
可以看到上图中的运行结果,使用 @Bean 方法注解的方式和五大 类注解结合使用,也是可以获取到 Bean 对象的。
2. @Bean 方法注解的重命名
可以看到下图的运行结果:
注:此时如果是设置了别名之后,就不能再用原类名去获取 Bean 对象了,只能使用别名 或者别名之一 来获取对象。