第四天注入(lnjection)
什么是注入
通过spring工厂及配置文件,为所创建对象的成员变量赋值
为什么要注入
通过编码的方式,为成员变量赋值,存在耦合
注入方式
XML方式
Get/Set注入
针对不同类型的成员变量,在标签,需要嵌套其他标签
(1)基本数据类型注入,以及list,set,map,Properties的注入
<bean id="persion" class="com.spring.context.basic.Persion">
<!--基本数据类型注入-->
<property name="id">
<value>10</value>
</property>
<!--简写-->
<property name="name" value="sss"/>
<!--数组的注入-->
<property name="emails">
<list>
<value>925</value>
<value>22</value>
</list>
</property>
<!--list的注入-->
<property name="addresses">
<list>
<value>1</value>
<value>1</value>
</list>
</property>
<!--set的注入-->
<property name="tels">
<set>
<value>1</value>
<value>2</value>
</set>
</property>
<!--Map-->
<property name="qqs">
<map>
<entry>
<key><value>123</value></key>
<value>bbb</value>
</entry>
<entry>
<key><value>123</value></key>
<value>bbb</value>
<!--
可以<ref></ref>
-->
</entry>
</map>
</property>
<!--Properties-->
<property name="p">
<props>
<prop key="k1">sdf</prop>
<prop key="k2">sd2f</prop>
</props>
</property>
</bean>
(2)用户自定义类型的注入
①为成员变量提供get/set方法
②配置文件注入
方式一:文件代码冗余,并且userDao多次注入,多次创建,浪费资源
<bean id="userService" class="com.designpatterns.factory.test2.UserServiceImpl">
<property name="userDAO">
<bean class="com.designpatterns.factory.test2.UserDAOImpl"/>
</property>
</bean>
<bean id="userService1" class="com.designpatterns.factory.test2.UserServiceImpl">
<property name="userDAO">
<bean class="com.designpatterns.factory.test2.UserDAOImpl"/>
</property>
</bean>
方式二:
<bean id="userDAO" class="com.designpatterns.factory.test2.UserDAOImpl"/>
<bean id="userService3" class="com.designpatterns.factory.test2.UserServiceImpl">
<property name="userDAO">
<ref bean="userDAO"/>
</property>
</bean>
<bean id="userService4" class="com.designpatterns.factory.test2.UserServiceImpl">
<property name="userDAO">
<ref bean="userDAO"/>
</property>
</bean>
<!-- 简写-->
<bean id="userService5" class="com.designpatterns.factory.test2.UserServiceImpl">
<property name="userDAO" ref="userDAO"/>
</bean>
(3)基于p命名空间简化
①引入p命名空间
xmlns:p="http://www.springframework.org/schema/p"
②使用
1.基本数据类型
<bean id="persion2" class="com.spring.context.basic.Persion" p:name="sds"/>
2.用户自定义类型
<bean id="userService2" class="com.designpatterns.factory.test2.UserServiceImpl" p:userDAO-ref="userDAO"/>
构造器方式注入
使用进行注入
(1)创建类型
package com.designpatterns.factory.test2;
import java.io.Serializable;
public class User implements Serializable {
private String name;
private String password;
public User() {
}
public User(String name, String password) {
this.name = name;
this.password = password;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", password='" + password + '\'' +
'}';
}
}
(2)在配置文件中注入
<bean id="user" class="com.designpatterns.factory.test2.User">
<constructor-arg>
<value>1</value>
</constructor-arg>
<constructor-arg>
<value>2</value>
</constructor-arg>
</bean>
注意:
①构造器个数不同数,通过控制 标签的数量进行区分
②构造器个数相同时,通过 中的type属性进行类型区分
Java代码注入
(1)通过@Bean注入到配置Java类中
package com.bean.explicitjava.config;
import com.bean.basic1.CDPlayer;
import com.bean.basic1.CompactDisc;
import com.bean.basic1.SgtPeppwes;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
/**
*@ComponentScan让spring启用组件扫描
* @author PitterWang
* @create 2020/6/5
* @since 1.0.0
*/
@Configuration
@ComponentScan()
public class CDPlayerConfig {
/**
* 把CompactDisc注入到当前配置文件中
* @return
*/
@Bean("blankDisc")
public CompactDisc setSgt(){
return new SgtPeppwes();
}
/**
* 将CDPlayer配置到当前配置文件中、并且把CompactDisc注入到CDPlayer中
* @return
*/
@Bean("cdPlayer")
public CDPlayer setCd(){
return new CDPlayer(setSgt());
}
}
(2)使用,通过AnnotationConfigApplicationContext获取
public class Test {
@org.junit.Test
public void test(){
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(CDPlayerConfig.class);
CompactDisc blankDisc = (CompactDisc)applicationContext.getBean("blankDisc");
blankDisc.play();
CDPlayer cdPlayer = (CDPlayer)applicationContext.getBean("cdPlayer");
cdPlayer.play();
}
}
自动化注入
(1)在要注入的类中加上@Component,说明当前类是是一个组件类,告诉Spring要为这个类创建bean,注入到Spring工厂当中
package com.bean.basic;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* @author PitterWang
* @create 2020/6/5
* @since 1.0.0
*/
@Component
public class CDPlayer implements MediaPlayer{
/***
* @Autowired进行自动装配
* required属性设置为false时,Spring会尝试自动装配,如果没有匹配的bean时,Spring将这个bean处于未装配状态
* 可以用在属性,构造器和set方法或者任何方法之上 相当于把CompactDisc自动装配到当前方法中
* @param compactDisc
*/
private CompactDisc compactDisc;
public CDPlayer() {
}
@Autowired
public CDPlayer(CompactDisc compactDisc) {
this.compactDisc = compactDisc;
}
public CompactDisc getCompactDisc() {
return compactDisc;
}
public void setCompactDisc(CompactDisc compactDisc) {
this.compactDisc = compactDisc;
}
@Override
public void play() {
System.out.println("CD加载~~");
compactDisc.play();
}
}
(2)通过ComponentScan进行扫描
@Configuration
@ComponentScan(value = "com.bean.basic")
public class CDPlayerConfig {
}
(3)测试
package com.bean.scanning.test;
import com.bean.basic.CompactDisc;
import com.bean.basic.MediaPlayer;
import com.bean.scanning.config.CDPlayerConfig;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* 〈〉
* @RunWith(SpringJUnit4ClassRunner.class) SpringJUnit4ClassRunne以便测试开始的时候自动创建Spring应用上下问
* @ContextConfiguration(classes = CDPlayerConfig.class)告诉SpringJUnit4ClassRunne需要到CDPlayerConfig中加载配置文件
* @Autowired注入
*
*
* 总结:通过@Component表示该类是一个组件类,告诉Spring要为这个类创建bean,注入到Spring工厂当中
* 通过@Configuration表示当前类时一个配置类
* 通过@ComponentScan(value = "com.scanning.basic") 进行扫描,把这部分的bean注入到当前当前工厂当中
* 通过@ContextConfiguration(classes = CDPlayerConfig.class) 进行扫描配置文件,把bean工厂实例化到当前类中
* 通过@Autowired 进行装配到当前类中,在当前类中进行使用
*
* @author PitterWang
* @create 2020/6/5
* @since 1.0.0
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = CDPlayerConfig.class)
public class CDPlayerTest {
@Autowired
private CompactDisc compactDisc;
@Autowired
private MediaPlayer mediaPlayer;
@Test
public void test(){
compactDisc.play();
}
@Test
public void test1(){
mediaPlayer.play();
}
}