方法注解(@Bean)
类注解是添加到某个类上的,⽽⽅法注解是放到某个⽅法上的:
Student 类:
//普通类 public class Student { private String name; private int id; private int score; @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", id=" + id + ", score=" + score + '}'; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } public int getScore() { return score; } public void setScore(int score) { this.score = score; } }
class 类:
//注意: 方法注解要配合五大类注解一起使用 // 该类也存储在 IoC 容器中 @Controller public class Class { //使用方法注解, 将方法的返回值存储到 IoC 容器中 @Bean public Student student() { Student student = new Student(); student.setId(6); student.setName("张三"); student.setScore(150); return student; } }
获取 bean 对象:
public class App { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml"); //注意:@Bean 默认命名是方法名 // 也就是添加方法注解的那个方法名 Student student = context.getBean("student", Student.class); System.out.println(student.toString()); } }
@Bean 还有几种重命名方式:
@Bean("aaa")
@Bean(value = "sss")
@Bean(name = "nnn")
点入 @Bean :
发现 name 和 value 效果是一样的。
除了取单个名称外,还可以取多个名称:
@Bean(value = {"sss","888"})
@Bean(name = {"sss","888"})
@Bean({"sss","888"})
注意:
- 如果重命名了,那么获取 bean 对象时,默认的方法获取 bean 对象的方式就不能用了。
- 添加了 @Bean 注解的方法无法传参(方法的调用是程序在控制),也就不能重载。
- 如果多个 Bean 使用相同的名称,那么程序执行不会报错,但是第一个 Bean 后的对象不会被放到容器中,也就是只有第一次创建 Bean 的时候会将对应的 Bean 名称关联起来,后续再有相同名称的 Bean 存储的时候,容器会自动忽略。
获取 Bean 对象 (@Autowired)
获取 bean 对象也叫做对象装配,是把对象取出来放到某个类中,有时候也叫对象注⼊。
属性注入
属性注⼊是使⽤ @Autowired 实现的:
普通类 User:
public class User { private int id; private String name; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "User{" + "id=" + id + ", name='" + name + '\'' + '}'; } }
添加类注解的 UserService:
@Service public class UserService { public User getUser(int id, String name) { User user = new User(); user.setId(id); user.setName(name); return user; } }
添加类注解的 UserController:
@Controller public class UserController { //使用属性注入,将IoC容器中的UserService类型的对象 //注入变量 userService中 @Autowired private UserService userService; public User getUser(int id, String name) { return userService.getUser(id,name); } }
注意:下面我们不使用 @Autowired 来进行依赖注入,因为 main 函数是静态方法,@Autowired 又不能给局部变量注入,那就只能放在类里面方法外面了,再加上 static 修饰 才能在 main 里访问,但可惜的是静态类属于方法的一部分,static 成员是不能使用 @Autowired 来注入。
public class Test { public static void main(String[] args) { //依赖查找 ApplicationContext context = new ClassPathXmlApplicationContext("spring-context.xml"); UserController userController = context.getBean("userController", UserController.class); //检验是否得到了 UserController 类型对象 System.out.println(userController.getUser(3,"张三").toString()); } }
依赖查找 VS 依赖注入
依赖查找:依赖 Bean 的名称来获取 Bean 对象。
依赖注入:通过注解 @Autowired 根据对象类型进行依赖注入,首先根据 getType 从容器中获取对象,如果 IoC 容器中只有一个该类型对象,则直接注入到当前属性上;如果容器中有多个该类型对象,则会使用 getName (根据名称)进行匹配。(具体体现如下)