目录
注入(injection)
什么是注入:
1,spring通过spring工厂及其配置文件,为对象的成员变量赋值。普通代码(通过手动书写代码调用getter和setter赋值)
2,如何进行注入(开发步骤)
1,类的成员变量提供相应的setter和getter方法。2,在spring配置文件中配置。
<bean id="person" class="begin.Person">
<property name="name" value="tomas"/>
<property name="age" value="21"/>
</bean>
调用结果:
实质上是通过get和set方式赋值(你可以在get和set方法上添加一句话输出试试)
3,注入的好处:解耦合(一开始赋值是在代码中set,现在是XML中配置);
原理分析:反射。
8中基本类型+string直接在value属性或者<value></value>标签中书写即可。
基础类型注入详情:
String,int,string[],List,Map,Properties。
public class KindsValue {
private String[]names;
private Set<Integer>set;
private List<Integer> list;
private Map<String,Integer>map;
private Properties properties;
//get和setter略
}
XML配置文件配置如下:
<bean id="kindsValue" class="begin.KindsValue">
<!-- 数组有个asList方法(可以认为就是集合) -->
<property name="names">
<list>
<value>alice</value>
<value>jack</value>
</list>
</property>
<!-- set标签在外 -->
<property name="set">
<set>
<value>1</value>
<value>2</value>
<value>3</value>
</set>
</property>
<!--list标签-->
<property name="list">
<list>
<value>4</value>
<value>5</value>
<value>6</value>
</list>
</property>
<!-- map标签,map.entry是一组-->
<property name="map">
<map>
<entry>
<key><value>1</value></key>
<value>1</value>
</entry>
<entry>
<key><value>2</value></key>
<value>2</value>
</entry>
<entry>
<key><value>3</value></key>
<value>3</value>
</entry>
</map>
</property>
<!-- properties是特殊的map,key=string=value-->
<property name="properties">
<props>
<prop key="key1">value1</prop>
<prop key="key2">value2</prop>
</props>
</property>
</bean>
test代码如下:
/**
* 用于测试:spring属性注入
*/
@org.junit.Test
public void test2(){
ApplicationContext ctx = new ClassPathXmlApplicationContext("/applicationContext.xml");
KindsValue kindsValue = (KindsValue) ctx.getBean("kindsValue");
System.out.println("name数组");
for (String name : kindsValue.getNames()) {
System.out.println(name);
}
System.out.println("set");
for (Integer integer : kindsValue.getSet()) {
System.out.println(integer);
}
System.out.println("list");
for (Integer integer : kindsValue.getList()) {
System.out.println(integer);
}
System.out.println("map");
Iterator<Map.Entry<String, Integer>> iterator = kindsValue.getMap().entrySet().iterator();
while(iterator.hasNext()){
Map.Entry<String, Integer> entry = iterator.next();
System.out.println(entry.getKey());
System.out.println(entry.getValue());
}
System.out.println("properties");
Properties properties = kindsValue.getProperties();
System.out.println("key1 "+properties.get("key1"));
System.out.println("key2 "+properties.get("key2"));
}
结果如下:
最重要的就是外面的标签!
复杂的JDK类型如date(spring内置的处理string->date格式 类似于:2020/08/25)
用户自定义类型(对象类型)
创建对象类型:
public interface IUserDao {
public void save(Person person);
public void query(String name);
}
public interface IUserService {
public void register(Person person);
public void login(String name);
}
public class UserDaoImpl implements IUserDao{
@Override
public void save(Person person) {
System.out.println("dao save...");
}
@Override
public void query(String name) {
System.out.println("dao query name "+ name);
}
}
public class UserServiceImpl implements IUserService {
private IUserDao userDao;
public IUserDao getUserDao() {
return userDao;
}
public void setUserDao(IUserDao userDao) {
this.userDao = userDao;
}
@Override
public void register(Person person) {
System.out.println("service..register");
userDao.save(person);
}
@Override
public void login(String name) {
System.out.println("service..login");
userDao.query(name);
}
}
XML配置:
<!-- 这是最简单有效的格式,记住就行-->
<bean id="userDao" class="core.UserDaoImpl"></bean>
<bean id="userService" class="core.UserServiceImpl">
<!-- 在外部引用创建过的,spring会自动为其注入-->
<property name="userDao" ref="userDao"></property>
</bean>
test代码:
/**
* 测试:自定义类型的注入
*/
@org.junit.Test
public void test3(){
ApplicationContext ctx = new ClassPathXmlApplicationContext("/applicationContext.xml");
IUserService userService = (IUserService) ctx.getBean("userService");
userService.login("tomas");
}
结果:
构造注入
顾名思义:就是应用构造方法的注入。
注入:通过spring的配置文件,为成员变量赋值;
前面学的是setter注入。spring中调用set方法,通过配置文件 为成员变量赋值
而构造注入则是在构造方法中 spring调用构造方法 通过配置文件 为成员赋值
例如给Person类构造注入:必须有多参的构造方法。
配置文件:
<bean id="person" class="begin.Person" >
<constructor-arg value="jack"/>
<constructor-arg value="18" />
</bean>
结果:
若要给某个参数构造注入时,要指定类型(type属性)。
特别的:构造注入和set注入同时存在时,set注入会把构造注入给覆盖掉。
注入总结:
两种注入:set注入和构造注入。推荐set注入。因为构造注入会有方法的重载,比较麻烦。(spring自己也有注入的需求,它用的就是set注入)。
反转控制与依赖注入:
1,反转控制 -IOC(inverse of control)控制:指的是对 对象属性的赋值的控制。以前在代码中手动赋值。现在:spring框架自动赋值。
2,依赖注入(dependency injection -DI)注入:通过spring工厂及其配置文件,为对象bean,component的成员赋值。
依赖注入:当一个类需要另一个类时,就意味着依赖,一旦出现依赖,就可以把另一个对象作为本类的成员变量,最终通过spring配置文件进行注入(赋值)。