B站学习笔记
DI依赖注入
依赖:bean 的创建依赖容器
注入:bean 对象的所有属性由容器注入
使用DI原理,代码更加简洁,当为对象提供依赖项时,去耦会更有效。该对象不查找其依赖项,并且不知道依赖项的位置或类。结果,您的类变得更易于测试,尤其是当依赖项依赖于接口或抽象基类时,它们允许在单元测试中使用存根或模拟实现。
DI存在两个主要变体:基于构造函数的依赖注入和[基于Setter的依赖注入]
ApplicationContext context =
new ClassPathXmlApplicationContext("Beans.xml");
HelloWorld obj = (HelloWorld) context.getBean("helloWorld");
obj.getMessage();
<?xml version="1.0" encoding="UTF-8
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="helloWorld" class="com.tutorialspoint.HelloWorld">
<property name="message" value="Hello World!"/>
对成员变量赋值
</bean>
</beans>
基于构造函数的依赖注入
ApplicationContext context =
new ClassPathXmlApplicationContext("Beans.xml");
HelloWorld obj = (HelloWorld) context.getBean("helloWorld");
obj.getMessage();
-
使用无参构造创建对象,默认
-
使用有参构造函数创建对象
-
下标赋值
<constructor-arg index = "0" value="111"/> <constructor-arg index="1" value="7500000"/> <constructor-arg index="2" value="42"/>
解决多个简单值的歧义性之外,指定索引还可以解决歧义,其中构造函数具有两个相同类型的参数
-
构造函数参数类型匹配
过使用
type
属性显式指定构造函数参数的类型,则容器可以使用简单类型的类型匹配<constructor-arg type="int" value="111"/> <constructor-arg type="java.lang.String" value="22"/>
-
直接参数名设置
<bean id="User" class="com.huliyong.domain.User"> <constructor-arg name="name" value="张三"/> </bean>
传入的是pojo (传入的是work)
<bean id="User" class="com.huliyong.domain.User"> <constructor-arg ref="work"/> </bean> <bean id="work" class="com.huliyong.domain.work"/>
在配置文件加载的时候 容器中管理的对象就已经初始化了
-
基于setter的依赖注入
基于设置器的DI是通过在调用无参数构造函数或无参数static
工厂方法以实例化您的bean 之后,在您的bean上调用setter方法来完成的。
下面的示例显示只能通过使用纯setter注入来依赖注入的类。此类是常规的Java。它是一个POJO,不依赖于特定于容器的接口,基类或注释
public class SimpleMovieLister {
private MovieFinder movieFinder;
public void setMovieFinder(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}
}
[环境搭建]
public class address {
private String address;
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
public class Student {
private address address;
private String name;
private String[] book;
private List<String> hobbys;
private Map<String ,String> card;
private Set<String > games;
private String wife;
private Properties info;
}
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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="address" class="com.huliyong.domain.address">
<property name="address" value="安徽"/>
</bean>
<bean id="student" class="com.huliyong.domain.Student" >
<!--普通注入-->
<property name="name" value="胡"/>
<!--Bean注入 ref -->
<property name="address" ref="address"/>
<!--数组注入-->
<property name="book">
<array>
<value>茶馆</value>
<value>朝花夕拾</value>
<value>活着</value>
</array>
</property>
<!--list 注入-->
<property name="hobbys">
<list>
<value>学习</value>
<value>听歌</value>
<value>打游戏</value>
</list>
</property>
<!--map-->
<property name="card">
<map>
<entry key="身份证" value="123123123123"/>
<entry key="银行卡" value="213123123312312"/>
</map>
</property>
<!--set-->
<property name="games">
<set>
<value>lol</value>
<value>cf</value>
<value>wzry</value>
</set>
</property>
<!--空值注入-->
<property name="wife">
<null/>
</property>
<property name="info">
<props>
<prop key="学号">123123</prop>
<prop key="username">张三</prop>
<prop key="url">男</prop>
</props>
</property>
</bean>
</beans>
测试
import com.huliyong.domain.Student;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class mytest {
@Test
public void test(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
Student student = (Student) applicationContext.getBean("student");
System.out.println(student.toString());
/*
Student{address=address{address='安徽'},
name='胡',
book=[茶馆, 朝花夕拾, 活着],
hobbys=[学习, 听歌, 打游戏],
card={身份证=123123123123,
银行卡=213123123312312},
games=[lol, cf, wzry],
wife='null',
info={学号=123123, url=男, username=张三}}
* */
}
}
扩展注入
利用p 标签或者 c 标签进行注入
首先导入xml 约束
xmlns:p="http://www.springframework.org/schema/p" xmlns:c="http://www.springframework.org/schema/c"
<?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-3.0.xsd">
<!--p命名空间 可以直接注入属性值-->
<bean id="user" class="com.huliyong.domain.User" p:name="李四" p:age="12">
</bean>
<!--c命名空间 可以通过构造器注入-->
<bean id="user2" class="com.huliyong.domain.User" c:name="李四2" c:age="12"/>
</beans>
The p-namespace is not as flexible as the standard XML format. For example, the format for declaring property references clashes with properties that end in Ref
, whereas the standard XML format does not
p命名空间不如标准XML格式灵活。
spring 配置
别名
<!--别名-->
<alias name="User" alias="user2"/>
注意:区分大小写
Bean配置
- id : bean 的唯一 标识符,也就是相当于我们学的对象
- class:bean对象所对应的全限定名:包名+类型
- name :也是别名,而且name可以同时取多个别名
<bean id="user" class="com.huliyong.domain.User" name="user3,name4">
</bean>
import
一般用于团队开发使用 把多个配置文件导入合并成一个
项目最后读取的是applicationContext.xml 配置文件
bean1.xml
bean2.xml
bean3.xml
在applicationContext.xml 中写入
<import resource="Bean1.xml"/>
<import resource="Bean2.xml"/>
<import resource="Bean3.xml"/>