DI也就是依赖注入。在传统的程序设计过程中,调用者需要直接使用new关键字创建被调用者的实例,调用者和被调用者之间的耦合度很高,要由调用者亲自创建被调用者的实例对象,这样不利于软件的移植与维护。但在Spring中创建被调用者的工作不再由调用者来完成,SpringIOC容器系统运行时会动态的向某个对象提供它所需要的其他对象,不像以前需要new一个出来。那么如何提供呢?Spring的DI依赖注入实现了该功能。其实,说的通俗点,依赖注入就是对对象中的属性进行赋值的过程,只是现在这个过程不需要我们自己来做,而交由SpringIOC容器来做。
package org.spring;
public class Student {
private String name;
private int age;
private Bicycle bicycle;
public Student(String name, int age, Bicycle bicycle) {
this.name = name;
this.age = age;
this.bicycle = bicycle;
}
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;
}
public Bicycle getBicycle() {
return bicycle;
}
public void setBicycle(Bicycle bicycle) {
this.bicycle = bicycle;
}
}
public Student(String name, String address, Bicycle bicycle) {
this.name = name;
this.address = address;
this.bicycle = bicycle;
}
public class DITest {
@Test
public void test() {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Student student = (Student) context.getBean("student");
System.out.println(student.getName() + " : " + student.getAge() + " : " + student.getBicycle());
}
}
package org.spring;
public class Student {
private String name;
private int age;
private Bicycle bicycle;
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;
}
public Bicycle getBicycle() {
return bicycle;
}
public void setBicycle(Bicycle bicycle) {
this.bicycle = bicycle;
}
}
public Student(String name, int age, Bicycle bicycle) {
this.name = name;
this.age = age;
this.bicycle = bicycle;
}
public Bicycle(Student student) {
this.student = student;
}
第二种形式是使用ref的local属性指定目标bean,它可以利用XML解析器来验证所引用的bean是否存在同一文件中。local属性值必须是目标bean的id属性值。如果在同一配置文件中没有找到引用的bean,XML解析器将抛出一个例外。如果目标bean是在同一文件内,使用local方式就是最好的选择(为了尽早地发现错误)。
第三种方式是通过使用ref的parent属性来引用当前容器的父容器中的bean。parent属性值既可以是目标bean的id值,也可以是name属性值。而且目标bean必须在当前容器的父容器中。使用parent属性的主要用途是为了避免引用父容器中的bean,该bean在子容器中与其相同的bean id值或name值(例如,子上下文中的一个bean定义覆盖了他的父bean)。
package org.spring.collection;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import org.spring.di.Student;
public class Collection {
private List list;
private Set set;
private Map map;
private Properties properties;
private Student student;
public List getList() {
return list;
}
public void setList(List list) {
this.list = list;
}
public Set getSet() {
return set;
}
public void setSet(Set set) {
this.set = set;
}
public Map getMap() {
return map;
}
public void setMap(Map map) {
this.map = map;
}
public Properties getProperties() {
return properties;
}
public void setProperties(Properties properties) {
this.properties = properties;
}
public Student getStudent() {
return student;
}
public void setStudent(Student student) {
this.student = student;
}
}
set : one
set : two
one
two
three
package org.spring.collection;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class CollectionTest {
@Test
public void test() {
ApplicationContext context = new ClassPathXmlApplicationContext(
"applicationContext.xml");
Collection collection = (Collection) context.getBean("collection");
System.out.println("============list集合============");
for (Object value : collection.getList()) {
System.out.println(value);
}
System.out.println("============set集合============");
for (Object value : collection.getSet()) {
System.out.println(value);
}
System.out.println("============map集合============");
for (Object key : collection.getMap().keySet()) {
System.out.println(key + " = " + collection.getMap().get(key));
}
System.out.println("============properties集合============");
for (Object key : collection.getProperties().keySet()) {
System.out.println(key + " = "
+ collection.getProperties().getProperty((String) key));
}
}
}
xmlns:context="http://www.springframework.org/schema/context"
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd"
我们知道注释本身是不会做任何事情的,它仅提供元数据信息。要使元数据信息真正起作用,必须让负责处理这些元数据的处理器工作起来,所以我们还需要
在spring配置文件中注册注解处理器,这样Spring容器才对会bean之间的依赖进行注入,该标签需要在
完成以上步骤后,我们只需在配置文件配置bean即可,而不用再配置对象之间的依赖关系。
@Autowired
private Bicycle bicycle;
@Autowired
public void setBicycle(Bicycle bicycle) {
this.bicycle = bicycle;
}
@Autowired
public Student(Bicycle bicycle) {
this.bicycle = bicycle;
}
@Autowired(required=false)
private Bicycle bicycle;
@Autowired
@Qualifier("bicycle2")
private Bicycle bicycle;
@Autowired
@Qualifier("bicycle")
private Bicycle bicycle;
@Autowired
public void setBicycle(@Qualifier("bicycle")Bicycle bicycle) {
this.bicycle = bicycle;
}
@Autowired
public Student(@Qualifier("bicycle") Bicycle bicycle) {
this.bicycle = bicycle;
}
@Resource
private Bicycle bicycle;
@Resource(name="bicycle")
private Bicycle bicycle;
@Resource(type=org.spring.annotation.Bicycle.class)
private Bicycle bicycle;
@Resource(type=org.spring.annotation.Bicycle.class,name="bicycle")
private Bicycle bicycle;
@Resource
public void setBicycle(Bicycle bicycle) {
this.bicycle = bicycle;
}
public class Person {
public Person() {
System.out.println("构造器");
}
@PostConstruct
public void init() {
System.out.println("washing......");
}
public void eat() {
System.out.println("eatting......");
}
@PreDestroy
public void destroy() {
System.out.println("wape mouth.....");
}
}
public class Person {
public Person() {
System.out.println("构造器");
}
@PostConstruct
public void init1() {
System.out.println("washing......1");
}
@PostConstruct
public void init2() {
System.out.println("washing......2");
}
public void eat() {
System.out.println("eatting......");
}
@PreDestroy
public void destroy1() {
System.out.println("wape mouth.....1");
}
@PreDestroy
public void destroy2() {
System.out.println("wape mouth.....2");
}
}
@Component
public class Student {
@Resource
private Bicycle bicycle;
public Bicycle getBicycle() {
return bicycle;
}
}
@Component
public class Bicycle {
}
public class AnnotationTest {
@Test
public void test() {
ApplicationContext context = new ClassPathXmlApplicationContext("org/spring/annotation/applicationContext.xml");
Student student = (Student) context.getBean("student");
System.out.println(student.getBicycle());
}
}