更加简单的存取Bean对象:
一. 五大类注解和一个方法注解
@Controllor:控制器,验证用户请求数据的正确性;【安保】
@Service:服务层,编排和调度具体的执行方法;【服务台】
@Repository:持久层,数据访问层,与数据库做交互;【执行者,数据访问】
@Component:组件,存放工具类;【工具】
@Configuration:配置项【基础配置】
@Bean【唯一的方法注解】
二.spring-config中配置扫描路径
其中,在com.bit.service中的类添加了五大类注解,可以被添加到Spring容器中,其他没在配置文件中扫描的路径,无法被添加到Spring容器
三、方法注解@Bean存取对象
默认情况下,原类名的首字母小写【小驼峰】或原类名【开头两个及以上的字母均为大写】
3.1存对象
@Component
public class UserBeans {
@Bean
public Student student1(){
Student student = new Student();
student.setAge(18);
student.setId(210210210);
student.setName("zhangsan");
return student;
}
@Bean
public Teacher teacher1(){
Teacher teacher = new Teacher();
teacher.setAge(25);
teacher.setId(22222222);
teacher.setName("老师");
return teacher;
}
}
存对象:在上述student1()和teacher1()方法中,都加了@Bean注解,该注解的作用是将被其修饰的方法的返回值存放到 Spring 中
3.2取对象
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
Teacher teacher = context.getBean("teacher1",Teacher.class);
teacher.sayHi();
}
取对象:将@Bean修饰的方法名和类型传给上下文对象进行获取
注意:
方法注解 1. ①方法名就是->实体名 ②类要有五大类注解,配合使用 ③必须要有返回值
2.
重命名,可以起多个名字 3. 当重命名之后,原方法名就不能获取到对象了
4. 允许同样的对象在Spring中存储多个
5. 存在不同方法中方法名相同且都被Bean修饰,可以通过@Order(int) 改变注入顺序,越小优先级越高
6.
可不可以和 包下同时使用------>可以
四、更简单的读取Bean【不能在启动类使用 static的优先级高于Spring】
1.属性注入 先判断类型读取,当有多个就根据起的变量名字进行读取【在属性上@Autowired】
缺点:①没办法实现final修饰的的变量注入②只适用于IoC中(兼容性不好)③违背单一设计原则概率更大
【UserService代码(伪代码)】
@Service
public class UserService {
public Teacher getUserById(int id){
//......
Teacher teacher =new Teacher();
teacher.setId(22);
System.out.println("UserService->getUserId");
return teacher;
}
}
【StudentController代码】
@Controller //将当前类存储到Spring中
public class StudentController {
@Autowired
private UserService userService;
public void sayHi(){
System.out.println("Student Hi~");
}
public Teacher getById(int id){
return userService.getUserById(id);
}
}
【启动类】
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
// Teacher teacher = context.getBean("teacher1",Teacher.class);
// teacher.sayHi();
StudentController studentController = context.getBean(StudentController.class);
studentController.getById(59);
}
其中体现是属性注入 的语句是:在属性上直接添加了@Autowired注解,直接从Spring容器中获取
2.Setter注入【普通的set方法】【在set方法上加@Autowired】
利用@Autowired给方法,可以给方法的参数中的对象进行注入
优点:每次只传递一个对象,符合单一设计原则
缺点:①没办法实现final修饰的的变量注入②使用Setter注入的对象可能会被修改
@Controller //将当前类存储到Spring中
public class StudentController {
private UserService userService;
//set注入
@Autowired
public void setUserService(UserService userService) {
this.userService = userService;
}
public void sayHi(){
System.out.println("Student Hi~");
}
public Teacher getById(int id){
return userService.getUserById(id);
}
}
区别于属性注入在于在set方法上加上@Autowired
3.构造方法注入(Spring官方推荐)【构造方法上加@Autowired】
如果仅有一个构造方法,可以不加@Autowired
优点:1.可以注入final的对象2.注入对象不会被改变(构造方法只执行一次)3.可以保证注入对象完全被初始化4.通用性更好
@Controller //将当前类存储到Spring中
public class StudentController {
//构造方法注入
private UserService userService;
@Autowired
public StudentController(UserService userService) {
this.userService = userService;
}
public void sayHi(){
System.out.println("Student Hi~");
}
public Teacher getById(int id){
return userService.getUserById(id);
}
}
在构造方法上加入@Autowired
问题:为什么构造方法可以注入一个不可变的对象,而属性注入和Setter不行?
答:在 Java 中规定被 final 对象必须满足一下两个条件的其中一个
①创建时直接赋值②构造方法赋值