Spring-02-依赖注入DI
五、依赖注入——DI
5.1 Setter注入(最常用)
-
实体类
public class Address { private String province; private String city; private String district; }
public class People { private String name; private Address address; private String[] cars; private List<String> phones; private Map<String, String> relationship; private Set<String> vips; private String wife; private Properties info; }
-
beans.xml配置
<bean id="address" class="com.pbx.pojo.Address"> <property name="province" value="浙江省"/> <property name="city" value="杭州市"/> <property name="district" value="西湖区"/> </bean> <bean id="bruce" class="com.pbx.pojo.People"> <!--常规注入--> <property name="name" value="BruceXu" /> <!--引用Bean进行注入--> <property name="address" ref="address"/> <!--注入数组--> <property name="cars"> <array> <value>奔驰</value> <value>奥迪</value> <value>宝马</value> </array> </property> <!--注入List--> <property name="phones"> <list> <value>iphone</value> <value>华为</value> <value>小米</value> </list> </property> <!--注入Map--> <property name="relationship"> <map> <entry key="老板" value="马云"/> <entry key="二次元老婆" value="蕾姆"/> </map> </property> <!--注入Set--> <property name="vips"> <set> <value>爱奇艺</value> <value>腾讯视频</value> <value>芒果tv</value> </set> </property> <!--注入空指针--> <property name="wife"> <null/> </property> <!--注入Properties--> <property name="info"> <props> <prop key="手机号">11122223333</prop> <prop key="身份证号">111111222222223333</prop> </props> </property> </bean>
-
测试
package com.pbx; import com.pbx.pojo.People; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * @author BruceXu * @date 2020/11/17 */ public class Test { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); People people = (People) context.getBean("bruce"); System.out.println(people); } }
5.2 构造器注入
-
实体类
public class Student { private int id; private String name; private String garde; public Student(int id, String name, String garde) { this.id = id; this.name = name; this.garde = garde; } }
-
beans.xml
<!--通过构造器参数下标注入--> <bean id="student1" class="com.pbx.pojo.Student"> <constructor-arg index="0" value="1"/> <constructor-arg index="1" value="张三"/> <constructor-arg index="2" value="一年级"/> </bean> <!--通过构造器形参名称注入--> <bean id="student2" class="com.pbx.pojo.Student"> <constructor-arg name="id" value="2"/> <constructor-arg name="name" value="李四"/> <constructor-arg name="garde" value="二年级"/> </bean> <!--通过参数类型注入--> <bean id="student3" class="com.pbx.pojo.Student"> <constructor-arg type="int" value="3"/> <constructor-arg type="java.lang.String" value="王五"/> <constructor-arg type="java.lang.String" value="三年级"/> </bean> <bean id="student4" class="com.pbx.pojo.Student"> <constructor-arg type="int" value="3"/> <constructor-arg type="java.lang.String" value="四年级"/> <constructor-arg type="java.lang.String" value="赵六"/> </bean>
-
测试
@Test public void test() { ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); Student student = (Student) context.getBean("student1"); System.out.println(student); System.out.println("=============="); student = (Student) context.getBean("student2"); System.out.println(student); System.out.println("=============="); student = (Student) context.getBean("student3"); System.out.println(student); System.out.println("=============="); student = (Student) context.getBean("student4"); System.out.println(student); }
5.3 命名空间注入
-
命名空间注入的方式可以简化Spring配置文件的编写,适用于简单类型属性的注入
-
实体类
public class User { private int id; private String name; private Address address; }
-
user.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:c="http://www.springframework.org/schema/c" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="user1" class="com.pbx.pojo.User" p:id="1" p:name="张三"/> <bean id="user2" class="com.pbx.pojo.User" c:id="2" c:name="李四"/> </beans>
-
测试
@Test public void test2() { ApplicationContext context = new ClassPathXmlApplicationContext("user.xml"); User user1 = context.getBean("user1", User.class); System.out.println(user1); User user2 = context.getBean("user2", User.class); System.out.println(user2); }
-
注意
-
要使用命名空间注入,需要导入命名空间的约束文件
xmlns:p="http://www.springframework.org/schema/p" xmlns:c="http://www.springframework.org/schema/c"
-
p命名空间和c命名空间实际上是代表标签
<property>
和<constructor-arg>
-
5.4 自动装配
-
Spring可以不用显式的配置bean的property属性,通过自动装配也可以完成Bean的注入
-
Spring‘的自动装配机制主要依赖两个操作
- 组件扫描:Spring会扫描被容器中的bean
- 自动装配:Spring会根据某些条件来自动装配那些设置了自动装配的Bean
-
常见的自动装配方式
byName
- Spring会自动寻找和bean中属性名同名的bean进行装配
byType
- Spring会自动寻找和bean中属性类型相同的bean进行装配。如果有多个类型相同的bean,那么要报错
-
环境搭建
-
实体类
public class People { private String name; private Dog dog; private Cat cat; }
public class Cat implements Pet { @Override public void shout() { System.out.println("Cat::shout()"); } }
public class Dog implements Pet { @Override public void shout() { System.out.println("Dog::shout()"); } }
-
beans.xml
<bean id="cat" class="com.pbx.pojo.Cat"/> <bean id="dog" class="com.pbx.pojo.Dog"/> <bean id="p1" class="com.pbx.pojo.People" autowire="byName"> </bean> <bean id="p2" class="com.pbx.pojo.People" autowire="byType"> </bean>
-
-
测试
@Test public void test01() { ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); People p1 = context.getBean("p1", People.class); People p2 = context.getBean("p2", People.class); p1.show(); System.out.println("================"); p2.show(); }