目录
前言
Spring中实现依赖注入的常见方式:
1、属性注入(Field Injection)【平时最常用的】
1.1、 @Autowired实现属性注入
属性注入的优缺点:
2、Setter注入(Setter Injection)
setter注入的优缺点
3、构造方法注入(Construction injection)【Spring官方推荐】
构造方法注入的优缺点
4、@Resource注解
@Resource VS @Autowired
5、同一类型多个@Bean报错
处理一:使用@Resource注解:
处理二:使用@Qualifier注解定义名称
小结:
前言
Spring中实现依赖注入的常见方式:
- 属性注入(Field Injection);
- Setter注入(Setter Injection);
- 构造方法注入(Construction Injection)
不会创建项目的小伙伴们,可以去我的主页往期中有介绍【依赖、配置等】,这一期就不介绍啦~
1、属性注入(Field Injection)【平时最常用的】
1.1、 @Autowired实现属性注入
属性注入是使用@Autowired实现的,将Service类注入到Controller类中
查看我这目录:
UserService中的代码:
package com.Service;
import org.springframework.stereotype.Service;
/**
* Created with IntelliJ IDEA.
* Description:
* User:龙宝
* Date:2023-02-07
* Time:14:51
*/
@Service
public class UserService {
public void sayHi() {
System.out.println("Hi,Service");
}
}
UserController中的代码:
package com.controller;
import com.Service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
/**
* Created with IntelliJ IDEA.
* Description:
* User:龙宝
* Date:2023-02-07
* Time:14:50
*/
@Controller
public class UserController {
//属性注入:
@Autowired
private UserService userService;
public void sayHi() {
userService.sayHi();
}
}
Test中的代码:
package com;
import com.Service.UserService;
import com.controller.UserController;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* Created with IntelliJ IDEA.
* Description:
* User:龙宝
* Date:2023-02-07
* Time:15:11
*/
public class Test {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
UserController userController = context.getBean("userController",UserController.class);
userController.sayHi();
}
}
输出:
属性注入的代码核心:
属性注入的优缺点:
优点:
缺点:
- 不能注入不可变对象【final修饰】
- 只适用于IoC容器
- 更容易违背单一设计原则【针对的对象是类】
2、Setter注入(Setter Injection)
Setter注入和属性注入方法实现类似,只是注解是加在set方法上
代码核心:
UserController_Setter中的代码:
package com.controller;
import com.Service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
/**
* Created with IntelliJ IDEA.
* Description:
* User:龙宝
* Date:2023-02-07
* Time:15:33
*/
@Controller
public class UserController_Setter {
//setter注入:
private UserService userService;
@Autowired
public void setUserService(UserService userService) {
this.userService = userService;
}
public void sayHi() {
userService.sayHi();
}
}
setter注入的优缺点
优点:
缺点:
- 不能注入不可变对象
- 注入对象可被修改【set方法是普通方法,可以被重复调用】
3、构造方法注入(Construction injection)【Spring官方推荐】
构造方法注入就是在类的构造方法中实现注入
核心代码:
UserController_Constructor中的代码:
package com.controller;
import com.Service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
/**
* Created with IntelliJ IDEA.
* Description:
* User:龙宝
* Date:2023-02-07
* Time:15:41
*/
@Controller
public class UserController_Constructor {
//构造方法注入:
private UserService userService;
@Autowired
public UserController_Constructor(UserService userService) {
this.userService = userService;
}
public void sayHi(){
userService.sayHi();
}
}
构造方法注入的优缺点
优点:
- 可以注入一个不可变对象
- 注入的对象不会被改变【一方面是加了final修饰符,另一方面是构造方法随着类加载只执行一次】
- 注入的对象会被完全初始化
- 通用性更好
缺点:
4、@Resource注解
@Resource注解是JDK自带的注解
使用:
这里的属性注入和setter注入和@Autowired是很类似的
@Resource VS @Autowired
相同点:
不同点:
- 功能支持:@Autowired支持属性注入、setter注入、构造方法注入;@Resource支持属性注入、setter注入,不支持构造方法注入
- 出身不同:@Autowired来自Spring框架;@Resource来自于JDK
- 参数支持不同:@Resource支持更多的参数设置;@Autowired只支持required参数
5、同一类型多个@Bean报错
目录:
我圈出来的目录是我们所在需要的:
首先需要一个User类:
package com.model;
/**
* Created with IntelliJ IDEA.
* Description:
* User:龙宝
* Date:2023-02-07
* Time:16:19
*/
public class User {
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
private String name;
private int age;
}
接下来是,UserBeans类,这里使用伪代码,只是方便我们去验证,实际工作中并不会这样子:
package com.component;
import com.model.User;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
/**
* Created with IntelliJ IDEA.
* Description:
* User:龙宝
* Date:2023-02-07
* Time:16:17
*/
@Component
public class UserBeans {
@Bean
public User user1() {
//伪代码
User user = new User();
user.setName("lyj");
user.setAge(19);
return user;
}
@Bean
public User user2() {
User user = new User();
user.setName("cyk");
user.setAge(20);
return user;
}
}
再接下来就是UserController类:
package com.controller;
import com.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
/**
* Created with IntelliJ IDEA.
* Description:
* User:龙宝
* Date:2023-02-07
* Time:16:35
*/
@Controller
public class UserController {
@Autowired
private User user;
public User getUser() {
return user;
}
}
最后在Test中运行:
package com;
import com.controller.UserController;
import com.controller.UserController1;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* Created with IntelliJ IDEA.
* Description:
* User:龙宝
* Date:2023-02-07
* Time:15:11
*/
public class Test {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
UserController userController = context.getBean("userController", UserController.class);
}
}
结果:
报错了,仔细看报错原因,
我们会看到:
也就是:同一类型多个@Bean报错
怎么处理:
处理一:使用@Resource注解:
处理二:使用@Qualifier注解定义名称
这里括号中名字怎么来的:
小结:
- 从Spring中获取对象:属性注入;Setter注入;构造方法注入
- 注入关键字:@Autowired;@Resource
- @Autowired和@Resource 不同:出身不同,参数设置不同【Resource支持更多参数设置,如name】
- 解决同一类型多个Bean报错:使用@Resource(name = “”);使用@Qualifier(“”)
本期结束啦,咱们下期见啦!