DI的三种实现方式
- 设置注入—Setter Injection
- 构造方法注入—Constructor Injection
- 接口注入—Interface Injection
public class Person{
private Dog dog;
private Ingteger age;
private String name;
//setter
//getter
}
<bean id="person" class="com.myspring.Person">
<property name="age" value="18"/>
<property name="name" value="胡八万"/>
<property name="dog" ref="dog"/>
</bean>
<bean id="dog" class="com.myspring.Dog">
<property name="name" value="二哈"/>
</bean>
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
Person person=ctx.getBean("person",Person.class);
这种方法要求属性必须实现setter
ref=""表示对象的引用
ref用来指向其他的bean
另外注入集合
< list >:注入一列值,允许重复
< set >:注入一列值,不允许重复
< map >:注入键(名)值对的集合,名称和值可以是任何类型
< props >:注入键(名)值对的集合,名称和值可以是任何类
private List list;
private Map map;
private Properties prop;
<bean id="mjc" class="com.myspring.JavaCollection">
<property name="list">
<!-- 注入集合 值可重复 set就不举例了-->
<list>
<value>list1</value>
<value>list1</value>
</list>
</property>
<property name="map">
<!-- 注入map -->
<map>
<entry key="小红">
<value>18</value>
</entry>
</map>
</property>
<property name="prop">
<!-- 注入properties -->
<props>
<prop key="小李">男</prop>
</props>
</property>
</bean>
还有一种有趣的方式spring表达式,类似于EL表达式,可以读取一个bean对象或者集合中的内容:#{bean.属性}
<bean id="personClone" class="com.myspring.Person">
<property name="age" value="#{person.age}"/>
<property name="name" value="#{person.name}"/>
</bean>
public Person(Integer age,String name,Dog dog){
this.age = age;
//...
}
<bean id="person" class="com.oak.entity.Person">
<constructor-arg index="1" value="八万"/>
<constructor-arg index="2" value="18"/>
<constructor-arg index="3" ref="dog"/>
</bean>
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
Person person=ctx.getBean("person",Person.class);
构造方法中的参数必须与配置文件中的参数个数一直否则报错
由于java中不会维护形参的名称,所以使用name属性进行注入时可能会有风险
public Person(Integer age,String args0,Dog dog){}
Interface Injection
它是在一个接口中定义需要注入的信息,并通过接口完成注入。Apache Avalon是一个较为典型的接口注入形IOC容器
以用户注册为例,首先定义一个接口,它的用途是将一个返回一个Person实例
public interface PersonInterfaceInject {
public Person getPerson();
}
同时,我们需要配置一个xml
<!-- Person的一个实例bean,定义每次返回不同的实例对象 -->
<bean id="liangzai" class="com.myspring.Person" p:name="胡八万"
p:age="18" scope="prototype" />
<!-- 实施方法注入 -->
<bean id="personInterfaceInject" class="com.myspring.PersonInterfaceInject">
<lookup-method name="getPerson" bean="liangzai" />
</bean>
最后测试一下
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
PersonInterfaceInject personInterfaceInject=applicationContext.getBean("personInterfaceInject",Person.class);
Person person1=personInterfaceInject.getPerson();
Person Person2=personInterfaceInject.getPerson();
System.out.println(person1);
System.out.println(person2);
System.out.println("person2==person1?:"+(person2==person1));
name:胡八万 age:18
name:胡八万 age:18
person2==person1?:false
最后输出可以看到person1和person2是不同实例
理解:“Lookup方法”可以使Spring替换一个bean原有的,获取其它对象具体的方法,并自动返回在容器中的查找结果。