Spring之DI依赖注入
6、(DI)依赖注入
DI与IOC的关系:
相同问题不同角度分析。
-
名称:property
-
类型:标签
-
归属:bean标签
-
作用:使用set方法的形式为bean提供资源
-
格式:
<bean> <property /> </bean>
-
基本属性:
<property name="propertyName" value="propertyValue" ref="beanId"/>
name:对应bean中的属性名,要求该属性必须提供可访问的set方法(严格规范为此名称是set方法对应名称)
value:设定非引用类型属性对应的值,不能与ref同时使用
ref:设定引用类型属性对应bean的id ,不能与value同时使用
- 注意:一个bean可以有多个property标签
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!--1.创建spring控制的资源-->
<!--bean可以使用多个名称,使用那么属性完成,中间使用,隔开-->
<bean id="userService" name="userService1" class="com.DI.service.Impl.UserServiceImpl">
<!--3.将要租注入的引用类型的变量通过property属性进行注入,对应的name是要注入的变量名 使用ref属性声明要注入的bean的id-->
<property name="userDao" ref="userDao"/>
<property name="num" value="666"/>
<property name="version" value="楠木"/>
</bean>
<!--将要注入的资源声明为bean,引用类型需要声明,非引用类型的不用声明,直接赋值-->
<bean id="userDao" class="com.DI.service.Impl.UserDaoImpl"/>
</beans>
6.1、构造器注入
-
名称:constructor-arg
-
类型:标签
-
归属:bean标签
-
作用:使用构造方法的形式为bean提供资源,兼容早期遗留系统的升级工作
-
格式:
<bean> <constructor-arg /> </bean>
-
基本属性:
<constructor-arg name="argsName" value="argsValue />
name:对应bean中的构造方法所携带的参数名
value:设定非引用类型构造方法参数对应的值,不能与ref同时使用
其他属性:
<constructor-arg index="arg-index" type="arg-type" ref="beanId"/>
ref:设定引用类型构造方法参数对应bean的id ,不能与value同时使用
type :设定构造方法参数的类型,用于按类型匹配参数或进行类型校验
index :设定构造方法参数的位置,用于按位置匹配参数,参数index值从0开始计数
- 注意:一个bean可以有多个constructor-arg标签
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!--将要注入的资源声明为bean,引用类型需要声明,非引用类型的不用声明,直接赋值-->
<bean id="userDao" class="com.DI.service.Impl.UserDaoImpl"/>
<bean id="userService" name="userService1" class="com.DI.service.Impl.UserServiceImpl">
<!--不加name,也可以加index:从0开始-->
<constructor-arg name="userDao" ref="userDao"/>
<constructor-arg name="num" value="66666"/>
<constructor-arg name="version" value="楠木"/>
</bean>
</beans>
6.2、Set方式注入【重点】
依赖注入:Set注入!
- 依赖:bean对象的创建依赖于容器!
- 注入: 上bean对象中的所有属性,由容器来注入!
【环境搭建】
1.复杂类型
package com.blue.pojo;
public class Address {
private String address;
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
2.真实测试对象
public class Student {
private String name;
private Address address;
private String[] books;
private List<String> hobbies;
private Map<String,String> card;
private Set<String> games;
private String wife;
private Properties into;
beans.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.xsd">
<bean id="student" class="com.blue.pojo.Student">
<!-- 第一种,普通注入,value -->
<property name="name" value="blue"/>
</bean>
</beans>
MyTest
public class MyTest {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
Student student = (Student) context.getBean("student");
System.out.println(student.getName());
}
}
集合注入方式:
-
名称:array,list,set,map,props
-
类型:标签
-
归属:property标签 或 constructor-arg标签
-
作用:注入集合数据类型属性
-
格式:
<property> <list></list> </property>
(1)集合类型数据注入——list
<property name="al">
<list>
<value>itheima</value>
<value>66666</value>
</list>
</property>
(2)集合类型数据注入——props
<property name="properties">
<props>
<prop key="name">itheima666</prop>
<prop key="value">666666</prop>
</props>
</property>
(3)集合类型数据注入——array (了解)
<property name="arr">
<array>
<value>123456</value>
<value>66666</value>
</array>
</property>
(4)集合类型数据注入——set(了解)
<property name="hs">
<set>
<value>itheima</value>
<value>66666</value>
</set>
</property>
(5)集合类型数据注入——map(了解)
<property name="hm">
<map>
<entry key="name" value="itheima66666"/>
<entry key="value" value="6666666666"/>
</map>
</property>
掌握:props、list
案例:
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!--1.创建spring控制的资源-->
<!--bean可以使用多个名称,使用那么属性完成,中间使用,隔开-->
<!-- <bean id="userService" name="userService1" class="com.DI.service.Impl.UserServiceImpl">
<!–3.将要租注入的引用类型的变量通过property属性进行注入,对应的name是要注入的变量名 使用ref属性声明要注入的bean的id–>
<property name="userDao" ref="userDao"/>
<property name="num" value="666"/>
<property name="version" value="楠木"/>
</bean>-->
<!--将要注入的资源声明为bean,引用类型需要声明,非引用类型的不用声明,直接赋值-->
<!--<bean id="userDao" class="com.DI.Dao.Impl.UserDaoImpl">
<!–不加name,也可以加index:从0开始–>
<constructor-arg name="password" value="12345"/>
<constructor-arg name="username" value="root"/>
<constructor-arg name="driver" value="123"/>
</bean>
<!–构造注入–>
<bean id="userService" name="userService1" class="com.DI.service.Impl.UserServiceImpl">
<!– 使用构造方法进行set注入,需要保障注入的属性与bean中定义的属性一致–>
<!–一致指顺序一致或类型一致或使用index解决问题–>
<constructor-arg name="userDao" ref="userDao"/>
<constructor-arg name="num" value="66666"/>
<constructor-arg name="version" value="楠木"/>
</bean>-->
<!--其余类型注入-->
<bean id="userDao" class="com.DI.Dao.Impl.UserDaoImpl">
<!--不加name,也可以加index:从0开始-->
<constructor-arg name="password" value="12345"/>
<constructor-arg name="username" value="root"/>
<constructor-arg name="driver" value="123"/>
</bean>
<bean id="userService" name="userService1" class="com.DI.service.Impl.UserServiceImpl">
<property name="userDao" ref="userDao"/>
<property name="bookDao" ref="bookDao"/>
</bean>
<bean id="bookDao" name="bookDao" class="com.DI.Dao.Impl.BookDaoImpl">
<property name="al">
<list>
<value>楠木1</value>
<value>楠木2</value>
</list>
</property>
<property name="props">
<props>
<prop key="name">小米</prop>
<prop key="value">大米</prop>
</props>
</property>
<property name="arr">
<array>
<value>6666</value>
<value>9999</value>
</array>
</property>
<property name="hs">
<set>
<value>楠木3</value>
<value>楠木4</value>
</set>
</property>
<property name="hm">
<map>
<entry key="name" value="楠木5"></entry>
<entry key="name" value="楠木6"></entry>
</map>
</property>
</bean>
</beans>
6.3、拓展方式注入
-
名称:p:propertyName,p:propertyName-ref
-
类型:属性
-
归属:bean标签
-
作用:为bean注入属性值
-
格式:
<bean p:propertyName="propertyValue" p:propertyName-ref="beanId"/>
-
注意:使用p命令空间需要先开启spring对p命令空间的的支持,在beans标签中添加对应空间支持
<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" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">
后续课程中还将开启其他的命名空间,方式同上
-
案例:
<bean id="userService" class="com.itheima.service.impl.UserServiceImpl" p:userDao-ref="userDao" p:bookDao-ref="bookDao" />
标签P
简化书写,直接注入属性值
xmlns:p="http://www.springframework.org/schema/p"
注意点: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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="user" class="com.lfs.pojo.User" p:name="blue" p:age="18"/>
</beans>
加配置–测试:
test:
public class MyTest {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("userbeans.xml");
User user = context.getBean("user", User.class);
System.out.println(user);
}
}
标签C
c标签:通过构造器注入
xmlns:c="http://www.springframework.org/schema/c"
public class User {
private String name;
private int age;
public User() {
}
public User(String name, int age) {
this.name = name;
this.age = age;
}
<bean id="user" class="com.blue.pojo.User" p:name="blue" p:age="18"/>
<bean id="user" class="com.blue.pojo.User" c:age="18" c:name="blue"/>
SpEL
-
Spring提供了对EL表达式的支持,统一属性注入格式
-
类型:属性值
-
归属:value属性值
-
作用:为bean注入属性值
-
格式:
<property value="EL表达式"></bean>
-
注意:所有属性值不区分是否引用类型,统一使用value赋值
-
所有格式统一使用 value=“********”
-
常量 #{10} #{3.14} #{2e5} #{‘itcast’}
-
引用bean #{beanId}
-
引用bean属性 #{beanId.propertyName}
-
引用bean方法 beanId.methodName().method2()
-
引用静态方法 T(java.lang.Math).PI
-
运算符支持 #{3 lt 4 == 4 ge 3}
-
正则表达式支持 #{user.name matches‘[a-z]{6,}’}
-
集合支持 #{likes[3]}
-
-
案例:
<bean id="userService" class="com.itheima.service.impl.UserServiceImpl"> <property name="userDao" value="#{userDao}"/> <property name="bookDao" value="#{bookDao}"/> <property name="num" value="#{666666666}"/> <property name="version" value="#{'itcast'}"/> </bean>
properties文件加载
-
Spring提供了读取外部properties文件的机制,使用读取到的数据为bean的属性赋值
-
操作步骤
1.准备外部properties文件
2.开启context命名空间支持
xmlns:context="http://www.springframework.org/schema/context"
3.加载指定的properties文件
<context:property-placeholder location="classpath:filename.properties">
4.使用加载的数据
<property name="propertyName" value="${propertiesName}"/>
-
注意:如果需要加载所有的properties文件,可以使用
*.properties
表示加载所有的properties文件 -
注意:读取数据使用**${propertiesName}格式进行,其中propertiesName**指properties文件中的属性名
<?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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
">
<!--1.加载context标签命名空间的支持-->
<!--xmlns:context="http://www.springframework.org/schema/context"
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
-->
<!--2.加载配置文件-->
<context:property-placeholder location="classpath:*.properties"/>
<!--1.创建spring控制的资源-->
<!--bean可以使用多个名称,使用那么属性完成,中间使用,隔开-->
<bean id="bookDao" class="com.properties.dao.Impl.BookDaoImpl"/>
<!--scope用于控制bean创建后的对象是否是单列-->
<bean id="userDao" class="com.properties.dao.Impl.UserDaoImpl">
<property name="name" value="${username}"/>
<property name="pass" value="${password}"/>
</bean>
<bean id="userService" class="com.properties.service.Impl.UserServiceImpl">
<property name="userDao" ref="userDao"/>
<property name="bookDao" ref="bookDao"/>
</bean>
</beans>
团队开发
-
名称:import
-
类型:标签
-
归属:beans标签
-
作用:在当前配置文件中导入其他配置文件中的项
-
格式:
<beans> <import /> </beans>
-
基本属性:
<import resource=“config.xml"/>
resource:加载的配置文件名
-
Spring容器加载多个配置文件
new ClassPathXmlApplicationContext("config1.xml","config2.xml");
-
Spring容器中的bean定义冲突问题
-
同id的bean,后定义的覆盖先定义的
-
导入配置文件可以理解为将导入的配置文件复制粘贴到对应位置
-
导入配置文件的顺序与位置不同可能会导致最终程序运行结果不同
-
ApplicationContext
-
1.ApplicationContext是一个接口,提供了访问spring容器的API
-
2.ClassPathXmlApplicationContext是一个类,实现了上述功能
-
3.ApplicationContext的顶层接口是BeanFactory
-
4.BeanFactory定义了bean相关的最基本操作
-
5.ApplicationContext在BeanFactory基础上追加了若干新功能
对比BeanFactory
-
1.BeanFactory创建的bean采用延迟加载形式,使用才创建
-
2.ApplicationContext创建的bean默认采用立即加载形式
FileSystemXmlApplicationContext
- 可以加载文件系统中任意位置的配置文件,而ClassPathXmlApplicationContext只能加载类路径下的配置文件
BeanFactory
Resource res = new ClassPathResource("applicationContext.xml");
BeanFactory bf = new XmlBeanFactory(res);
UserService userService = (UserService)bf.getBean("userService");
第三方资源配置—>Druid
-
阿里数据源方案Druid
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"></property> <property name="url" value="jdbc:mysql://localhost:3306/spring_ioc"></property> <property name="username" value="root"></property> <property name="password" value="root"></property> </bean>
- 点赞
- 收藏
- 关注作者
评论(0)