spring-DI
笔记
DI(Dependency Injection):
依赖:bean对象的创建依赖于容器
注入:bean对象中的所有属性,由容器来注入
接上一节笔记
1.父项目依赖(避免迷路)
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
2.创建子项目
新建两个实体类
public class Address {
private String name;
public Address() {
}
public Address(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Address{" +
"name='" + name + '\'' +
'}';
}
}
public class Student {
private String name;
private Address address;
private String[] books;
private List<String> lists;
private Map<String,String> stuNo;
private Set<String> games;
private String wife;
private Properties properties;
省略getset......
3.通过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 http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--
DI:
依赖:bean对象的创建依赖于容器
注入:bean对象中的所有属性,由容器来注入
-->
<bean id="address" class="com.gg.entity.Address">
<property name="name" value="广东xxx"/>
</bean>
<!--Set注入-->
<bean id="student" class="com.gg.entity.Student">
<!--字符串注入-->
<property name="name" value="晓晓"/>
<!--引用对象注入-->
<property name="address" ref="address"/>
<!--数组注入-->
<property name="books">
<array>
<value>1</value>
<value>2</value>
<value>3</value>
<value>4</value>
</array>
</property>
<!--list集合注入-->
<property name="lists">
<list>
<value>A</value>
<value>B</value>
<value>C</value>
<value>A</value>
</list>
</property>
<!--map集合注入-->
<property name="stuNo">
<map>
<entry key="length" value="6"/>
<entry key="type" value="String"/>
<entry key="value" value="123456"/>
</map>
</property>
<!--set集合注入(set集合没有重复的元素)-->
<property name="games">
<set>
<value>LOL</value>
<value>LOL</value>
<value>LOL1</value>
</set>
</property>
<!--空对象注入-->
<property name="wife">
<null/>
</property>
<!--properties注入-->
<property name="properties">
<props>
<prop key="server">tomcat</prop>
<prop key="port">8080</prop>
<prop key="url">https://www.baidu.com/</prop>
</props>
</property>
</bean>
</beans>
4.运行测试
@Test public void test(){ ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml"); Address address = context.getBean("address", Address.class); Student student = context.getBean("student", Student.class); System.out.println(student.toString()); System.out.println(address.toString()); } 输出:
Student{name='晓晓', address=Address{name='广东xxx'}, books=[1, 2, 3, 4], lists=[A, B, C, A],
stuNo={length=6, type=String, value=123456}, games=[LOL, LOL1], wife='null',
properties={port=8080, url=https://www.baidu.com/, server=tomcat}}
Address{name='广东xxx'}
5.c命名空间和p命名空间注入
新建bean.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">
<!--p命名空间注入-->
<bean id="address" class="com.gg.entity.Address" p:name="P注入"/>
<!--c命名空间注入-->
<bean id="address1" class="com.gg.entity.Address" c:name="C注入"/>
>
测试
@Test
public void test1(){
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:bean.xml");
Address address = context.getBean("address", Address.class);
Address address1 = context.getBean("address1", Address.class);
System.out.println(address.toString());
System.out.println(address1);
}
输出:
Address{name='P注入'}
Address{name='C注入'}
自动装配
创建三个实体类
public class Cat {
public void shout(){
System.out.println("喵喵叫........");
}
}
public class Dog {
public void shout(){
System.out.println("汪汪叫........");
}
}
public class People {
// @Autowired(required = false)
@Resource(name = "cat1")
private Cat cat;
@Autowired
@Qualifier("dog1")
private Dog dog;
@Value("自动注入")
private String name;
引入context约束
<?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/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--显式开启--> <context:annotation-config/> <bean id="dog" class="com.gg.entity.Dog"/> <bean id="dog1" class="com.gg.entity.Dog"/> <bean id="cat" class="com.gg.entity.Cat"/> <bean id="cat1" class="com.gg.entity.Cat"/> <bean id="people" class="com.gg.entity.People"/> </beans>
@Resource的作用相当于@Autowired,只不过@Autowired按byType自动注入,而@Resource默认按 byName自动注入罢了。@Resource有两个属性是比较重要的,分是name和type,Spring将@Resource注解的name属性解析为bean的名字,而type属性则解析为bean的类型。所以如果使用name属性,则使用byName的自动注入策略,而使用type属性时则使用byType自动注入策略。如果既不指定name也不指定type属性,这时将通过反射机制使用byName自动注入策略。
@Resource装配顺序
1. 如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常
2. 如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常
3. 如果指定了type,则从上下文中找到类型匹配的唯一bean进行装配,找不到或者找到多个,都会抛出异常
4. 如果既没有指定name,又没有指定type,则自动按照byName方式进行装配;如果没有匹配,则回退为一个原始类型进行匹配,如果匹配则自动装配;
@Autowired 与@Resource的区别:
1、 @Autowired与@Resource都可以用来装配bean. 都可以写在字段上,或写在setter方法上。
2、 @Autowired默认按类型装配(这个注解是属于spring的),默认情况下必须要求依赖对象必须存在,如果要允许null值,可以设置它的required属性为false,如:@Autowired(required=false) ,如果我们想使用名称装配可以结合@Qualifier注解进行使用
3、@Resource(这个注解属于J2EE的),默认按照名称进行装配,名称可以通过name属性进行指定,如果没有指定name属性,当注解写在字段上时,默认取字段名进行安装名称查找,如果注解写在setter方法上默认取属性名进行装配。当找不到与名称匹配的bean时才按照类型进行装配。但是需要注意的是,如果name属性一旦指定,就只会按照名称进行装配。
javaConfig
纯java类自动装配bean
1.使用people实例
public class Cat {
public void shout(){
System.out.println("喵喵叫........");
}
}
public class Dog {
public void shout(){
System.out.println("汪汪叫........");
}
}
public class People {
// @Autowired(required = false)
@Resource(name = "cat1")
private Cat cat;
@Autowired
@Qualifier("dog1")
private Dog dog;
@Value("自动注入")
private String name;
2.添加配置类管理bean
@Configuration // 相当于xml中的<context:annotation-config/>
@ComponentScan(basePackages = "com.gg.entity") // 相当于<context:component-scan base-package="com.gg.entity"/>
public class MyConfig {
@Bean // 相当于xml中的<bean></bean> 标签
/**
* 实际上就是
* <bean id="people1" class="com.gg.entity.People"/>
*/
public People people1(){
return new People();
}
@Bean
public Dog dog1(){
return new Dog();
}
@Bean
public Cat cat1(){
return new Cat();
}
}
3.测试
测试
@Test
public void test1(){
ApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
People people1 = context.getBean("people1", People.class);
people1.getCat().shout();
people1.getDog().shout();
System.out.println(people1);
}
输出:
喵喵叫........
汪汪叫........
People{cat=com.gg.entity.Cat@30ee2816, dog=com.gg.entity.Dog@31d7b7bf, name='自动注入'}

浙公网安备 33010602011771号