感兴趣的大家可以直接到官网看看 依赖注入
本篇主要用几个简单实例来具体介绍下依赖注入的几种方法。
- Constructor-based Dependency Injection 构造器注入
- 基于 Setter 的注入 Setter-based Dependency Injection
- 注解注入
我们以最基础的 xml 配置的方式为例。
依赖引入 spring-context 即可
org.springframework
spring-context
5.3.5
自定义实体类
package spring.ioc.dependency.injection.constructor;
public class User {
private final String name;
private final Integer age;
public User(String name,Integer age) {
this.name = name;
this.age=age;
}
@Override
public String toString() {
return "User{" +
"name='" + name + ''' +
", age=" + age +
'}';
}
}
配置文件 dependency-injection-construcor.xml 路径为 src/main/resources/MATE-INF/dependency-injection-construcor.xml 配置:constructor-arg
启动程序
package spring.ioc.dependency;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import spring.ioc.dependency.injection.constructor.User;
public class MainStart {
public static void main(String[] args) {
BeanFactory beanFactory=new ClassPathXmlApplicationContext("classpath:/MATE-INF/dependency-injection-construcor.xml");
User user = (User) beanFactory.getBean("user");
System.out.println(user);
}
}
运行结果:
User{name='搁浅', age=19}
这就是通过我们定义好的构造函数进行依赖的注入,当然注入的类型也可以是自定义的实体。
基于 Setter 的注入 Setter-based Dependency Injection这里我们在上面代码的基础上来进行一个 Setter 注入的 demo 演示
增加一个 Movie 实体类,并添加 set 方法
package spring.ioc.dependency.injection.setter;
import spring.ioc.dependency.injection.constructor.User;
public class Movie {
private String name;
private User user;
public void setName(String name) {
this.name = name;
}
public void setUser(User user) {
this.user = user;
}
@Override
public String toString() {
return "Movie{" +
"name='" + name + ''' +
", user=" + user +
'}';
}
}
配置文件更新,增加 movie bean 配置 property
主函数方法调用
public class MainStart {
public static void main(String[] args) {
BeanFactory beanFactory=new ClassPathXmlApplicationContext("classpath:/MATE-INF/dependency-injection-construcor.xml");
User user = (User) beanFactory.getBean("user");
Movie movie= (Movie) beanFactory.getBean("movie");
System.out.println(user);
System.out.println(movie);
}
}
运行结果:
User{name='搁浅', age=19}
Movie{name='长津湖战役', user=User{name='搁浅', age=19}}
实现 PropertyEditor 进行格式化注入
现在我们发现,Movie 依赖了 User 在注入的时候配置文件中,我们需要配置好 User 的 bean 然后再通过 ref 连接,有些时候这个链路可能会很长,导致配置很不清晰,Spring 对 JavaBean 的属性编辑器做了支持,这时我们可以通过自定义属性编辑器来进行优化。
首先继承 PropertyEditorSupport 并实现方法
package spring.ioc.dependency.injection.propertyeditor;
import spring.ioc.dependency.injection.constructor.User;
import java.beans.PropertyEditorSupport;
public class CommonUserPropertyEditor extends PropertyEditorSupport {
@Override
public void setAsText(String text) throws IllegalArgumentException {
if (text == null || text.indexOf(",") == -1) {
throw new IllegalArgumentException("设置的字符串格式不正确");
}
String[] infos = text.split(",");
User user = new User(infos[0], Integer.valueOf(infos[1]));
//2. 调用父类的setValue()方法设置转换后的属性对象
setValue(user);
}
}
实现 PropertyEditorRegistrar 将 CommonUserPropertyEditor 注册到 Spring 对 Bean 的处理流程中
package spring.ioc.dependency.injection.propertyeditor;
import org.springframework.beans.PropertyEditorRegistrar;
import org.springframework.beans.PropertyEditorRegistry;
import spring.ioc.dependency.injection.constructor.User;
public class CustomizedPropertyEditorRegistrar implements PropertyEditorRegistrar {
@Override
public void registerCustomEditors(PropertyEditorRegistry registry) {
registry.registerCustomEditor(User.class, new CommonUserPropertyEditor());
}
}
修改配置文件
主函数:
public class MainStart {
public static void main(String[] args) {
BeanFactory beanFactory=new ClassPathXmlApplicationContext("classpath:/MATE-INF/dependency-injection-construcor.xml");
User user = (User) beanFactory.getBean("user");
Movie movie= (Movie) beanFactory.getBean("movie");
System.out.println(user);
System.out.println(movie);
}
}
结果:
User{name='搁浅', age=19}
Movie{name='长津湖战役', user=User{name='搁浅', age=20}}
以上
应用上下文支持 constructor 注入 和 setter 注入,最直观的,constructor 注入 就是我们给定构造函数,在配置源信息中配置 constructor-arg 信息进行注入。 setter 注入 就是通过添加 set 方法,配置 property 进行注入。
同时也支持在已经通过 构造器注入一些依赖项后再 使用 setter 注入。
你可以 BeanDefinition 的形式来配置依赖,结合 PropertyEditor 实例一起使用,将属性从一种格式转换到另一种。
但是大多数情况我们不会这样使用,目前更加流行的方法是使用注解的方式 如 :@Component @Controller @Bean 此类。
注解注入最后介绍下最常用的注解注入
修改下主类的调用方法
@ComponentScan("spring.ioc.dependency.injection")
public class MainStart {
public static void main(String[] args) {
BeanFactory beanFactory=new AnnotationConfigApplicationContext("spring.ioc.dependency.injection");
User user = (User) beanFactory.getBean("user");
Movie movie= (Movie) beanFactory.getBean("movie");
System.out.println(user);
System.out.println(movie);
}
}
用户类,注意这里不需要定义构造函数
@Component("user")
public class User {
@Value(value = "搁浅")
private String name;
@Value(value = "19")
private Integer age;
@Override
public String toString() {
return "User{" +
"name='" + name + ''' +
", age=" + age +
'}';
}
}
电影类
@Repository("movie")
public class Movie {
@Value(value = "天下")
private String name;
@Resource
private User user;
@Override
public String toString() {
return "Movie{" +
"name='" + name + ''' +
", user=" + user +
'}';
}
}
运行:
User{name='搁浅', age=19}
Movie{name='天下', user=User{name='搁浅', age=19}}



