Spring——配置,依赖注入,Bean的自动装配
3.Spring配置
3.1、别名
<!--别名,如果添加了别名,我们也可以使用别名获取到这个对象-->
<alias name="user" alias="userNew"/>
3.2、Bean的配置
<!--
id : bean 的唯一标识符,也就是相当于我们学的对象名
class : bean 对象所对应的全限定名 : 包名 + 类型
name :也是别名,而且name 可以同时取多个别名
-->
<bean id="userT" class="com.jiang.pojo.UserT" name="user2 u2,u3;u4">
<property name="name" value="姜嘉航"/>
</bean>
3.3、import
这个import,一般用于团队开发使用,他可以将多个配置文件,导入合并为一个
假设,现在项目中有多个人开发,这三个人复制不同的类开发,不同的类需要注册在不同的bean中,我们可以利用import将所有人的beans.xml合并为一个总的!
比如现在有三个人写的xml配置文件:
-
张三(beans.xml)
-
李四(beans2.xml)
-
王五(beans3.xml)
-
applicationContext.xml(总的配置文件)
<import resource="beans.xml"/> <import resource="beans2.xml"/> <import resource="beans3.xml"/>
使用的时候,直接使用总的配置就行了。
4.依赖注入
4.1、构造器注入
前面IOC创建对象的方式就是构造器注入。
4.2、Set方式注入 【重点】
- 依赖注入:Set注入!
- 依赖:bean对象的创建依赖于容器!
- 注入: bean对象中的所有属性,由容器来注入!
环境搭建
-
复杂类型(地址类)
public class Address { private String address; public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } }
-
真实测试对象
package com.jiang.pojo; import lombok.Data; import java.util.*; @Data public class Student { private String name; private Address address; private String[] books; private List<String> hobbys; private Map<String,String> card; private Set<String> games; private String wife; private Properties info;// Properties文件 }
-
applicationContext.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 https://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="student" class="com.jiang.pojo.Student"> <!--第一种,普通值注入,value--> <property name="name" value="姜嘉航"/> </bean> </beans>
-
测试类
@Test public void testStudent(){ ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); Student student = (Student) context.getBean("student"); System.out.println(student); }
-
完善注入信息
<?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 id="address" class="com.jiang.pojo.Address"> <property name="address" value="西安"/> </bean> <bean id="student" class="com.jiang.pojo.Student"> <property name="name" value="姜嘉航"/> <property name="address" ref="address"/> <property name="books"> <array> <value>红楼梦</value> <value>西游记</value> <value>水浒传</value> <value>三国演义</value> </array> </property> <property name="list"> <list> <value>听歌</value> <value>画画</value> <value>学习</value> </list> </property> <property name="map"> <map> <entry key="身份证" value="654646654654654654654"/> <entry key="银行卡" value="6546461212654654654654654"/> </map> </property> <property name="set"> <set> <value>LOL</value> <value>王者荣耀</value> <value>魔兽世界</value> </set> </property> <property name="wife"> <null/> </property> <property name="info"> <props> <prop key="driver">12121</prop> <prop key="url">121212</prop> <prop key="username">root</prop> <prop key="password">12121</prop> </props> </property> </bean> </beans>
4.3、拓展方式注入
我们可以使用 p命令空间和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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!--p命名空间注入,可以直接注入属性的值:property-->
<bean id="user" class="com.jiang.pojo.User" p:name="姜嘉航" p:age="23"/>
<!--c命名空间注入,通过构造器注入:construct-args-->
<bean id="user2" class="com.jiang.pojo.User" c:age="23" c:name="姜嘉航"/>
</beans>
测试:
@Test
public void test2(){
ApplicationContext context = new ClassPathXmlApplicationContext("userbeans.xml");
User user = context.getBean("user2", User.class);
System.out.println(user);
}
注意点:p命名和c命名空间不能直接使用,需要导入xml约束!
xmlns:c="http://www.springframework.org/schema/c"
xmlns:p="http://www.springframework.org/schema/p"
5.Bean的自动装配
5.1、环境搭建
-
User对象
package com.jiang.entity; import lombok.Data; @Data public class User { private String name; private Cat cat; private Dog dog; }
-
Cat对象
package com.jiang.entity; public class Cat { private String name; public void shut(){ System.out.println("miao"); } }
-
Dog对象
package com.jiang.entity; public class Dog { private String name; public void shut(){ System.out.println("wang"); } }
5.2、ByName自动装配
<!--
byName: 自动寻找和属性相关的bean,本质set方法,会自动匹配个bean
-->
<bean id="people" class="com.kuang.pojo.People" autowire="byName">
<property name="name" value="姜嘉航"/>
</bean>
5.3、ByType自动装配
<bean id="dog" class="com.jiang.entity.Dog"/>
<bean id="cat" class="com.jiang.entity.Cat"/>
<!--
byType:根据这个属性的类型自动匹配,如果这个类型有多个bean就会报错
-->
<bean id="people" class="com.jiang.entity.User" autowire="byType">
<property name="name" value="姜嘉航"/>
</bean>
小结:
- byname的时候,需要保证所有bean的id唯一,并且这个bean需要和自动注入的属性的set方法的值一致!
- bytype的时候,需要保证所有bean的class唯一,并且这个bean需要和自动注入的属性的类型一致!
5.4、使用注解实现自动装配
jdk1.5支持的注解,Spring2.5就支持注解了!
The introduction of annotation-based configuration raised the question of whether this approach is “better” than XML.
要使用注解须知:
- 导入约束 : context约束
- ==配置注解的支持 :context:annotation-config/ 【重要】
<?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: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">
<context:annotation-config/>
</beans>
5.5、@Autowired
- 直接在属性上使用即可!也可以在set方式上使用!
- 使用Autowired 我们可以不用编写Set方法了,前提是你这个自动装配的属性在 IOC(Spring)容器中存在,且符合名字byname!
测试代码
public class People {
//如果显示定义了Autowired的required属性为false,说明这个对象可以为null,否则不允许为空
@Autowired(required = false)
private Cat cat;
@Autowired
private Dog dog;
private String name;
}
如果@Autowired自动装配的环境比较复杂,自动装配无法通过一个注解【@Autowired】完成的时候、我们可以使用@Qualifier(value="xxx")去配置@Autowired的使用,指定一个唯一的bean对象注入!
public class People {
@Autowired
@Qualifier(value="cat111")
private Cat cat;
@Autowired
@Qualifier(value="dog222")
private Dog dog;
private String name;
}
@Resource注解
public class People {
@Resource(name = "cat2")
private Cat cat;
@Resource
private Dog dog;
}
@Resource 和@ Autowired 的区别:
- 都是用来自动装配的,都可以放在属性字段上
- @ Autowired 通过byType的方式实现,而且必须要求这个对象存在! 【常用】
- @ Resource 默认通过byname的方式实现,如果找不到名字,则通过byType实现!如果两个都找不到的情况下,就报错! 【常用】
- 执行顺序不同:@ Autowired 通过byType的方式实现。@ Resource 默认通过byname的方式实现。