Spring 详细介绍<2>
一. 介绍一下spring中比较重要的名词:
1. IOC(Inversion of Control) 控制反转。
假设对象A依赖于对象B,那么对象A在初始化或者运行到某一点的时候,自己必须主动去创建对象B或者使用已经创建的对象B。无论是创建还是使用对象B,控制权都在自己手上。
软件系统在引入IOC容器之后,这种情形就完全改变了,由于IOC容器的加入,对象A与对象B之间失去了直接联系,所以,当对象A运行到需要对象B的时候,IOC容器会主动创建一个对象B注入到对象A需要的地方。
通过前后的对比,我们不难看出来:对象A获得依赖对象B的过程,由主动行为变为了被动行为,控制权颠倒过来了,这就是“控制反转”这个名称的由来。
2. IOC的别名:依赖注入(DI)
既然IOC是控制反转,那么到底是“哪些方面的控制被反转了呢?”,经过详细地分析和论证后,他得出了答案:“获得依赖对象的过程被反转了”。控制被反转之后,获得依赖对象的过程由自身管理变为了由IOC容器主动注入。于是,他给“控制反转”取了一个更合适的名字叫做“依赖注入(Dependency Injection)”。他的这个答案,实际上给出了实现IOC的方法:注入。所谓依赖注入,就是由IOC容器在运行期间,动态地将某种依赖关系注入到对象之中。
所以,依赖注入(DI)和控制反转(IOC)是从不同的角度的描述的同一件事情,就是指通过引入IOC容器,利用依赖关系注入的方式,实现对象之间的解耦。
IOC为我们带来了什么好处:无论两者中的任何一方出现什么的问题,都不会影响另一方的运行。这种特性体现在软件工程中,就是可维护性比较好,非常便于进行单元测试,便于调试程序和诊断故障。代码中的每一个Class都可以单独测试,彼此之间互不影响,只要保证自身的功能无误即可,这就是组件之间低耦合或者无耦合带来的好处。
二:通过spring容器访问容器中的bean。
BeanFactory是Spring容器最基本的接口,ApplicationContext是Spring容器中最常用的接口,它实现了BeanFactory,该接口有如下两个实现类:
-
ClassPathXmlApplicationContext:从类加载路径下搜索配置文件,并根据配置文件来创建Spring容器
-
FileSystemXmlApplicationContext:从文件系统的相对路径或绝对路径下去搜索配置文件,并根据配置文件来创建Spring容器
-
AnnotationConfigApplicationContext注解配置
config/spring/spring-servlet.xml 配置文件中配置的xml
<bean name="user" class="com.lq.play.model.User">
<property name="id" value="32324324"/>
<property name="username" value="lq"/>
<property name="password" value="123456"/>
<property name="salt" value="324343"/>
</bean>
ApplicationContext applicationContext = new
ClassPathXmlApplicationContext("config/spring/spring-servlet.xml");
User user = applicationContext.getBean("user", User.class);
System.out.println(user.toString());
ApplicationContext applicationContext1 = new FileSystemXmlApplicationContext("classpath:config/spring/spring-servlet.xml");
User user1 = applicationContext1.getBean("user",User.class);
System.out.println(user1.toString());
运行结果
User{id=32324324, username='lq', password='123456', salt='324343', locked=false}
User{id=32324324, username='lq', password='123456', salt='324343', locked=false}
三 通过设值注入即set方法注入
通过设值注入 基本类型、引用类型;list、map、set、properties
User.java
package com.lq.play.model;
import java.io.Serializable;
public class User implements Serializable {
private Long id;
private String username;
private String password;
private String salt;
private Boolean locked = Boolean.FALSE;
public User() {
}
public User(String username, String password) {
this.username = username;
this.password = password;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getSalt() {
return salt;
}
public void setSalt(String salt) {
this.salt = salt;
}
public String getCredentialsSalt() {
return username + salt;
}
public Boolean getLocked() {
return locked;
}
public void setLocked(Boolean locked) {
this.locked = locked;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
if (id != null ? !id.equals(user.id) : user.id != null) return false;
return true;
}
@Override
public int hashCode() {
return id != null ? id.hashCode() : 0;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
", salt='" + salt + '\'' +
", locked=" + locked +
'}';
}
}
UserMeta.java
package com.lq.play.model;
import java.util.*;
/**
* Created by lq on 2017/7/24.
*/
public class UserMeta {
private Set axes;
private Properties properties;
private int num;
private User user1;
private List<String> arrayList;
private Map<String, String> map;
private String description;
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public void setArrayList(List<String> arrayList) {
this.arrayList = arrayList;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public List<String> getArrayList() {
return arrayList;
}
public Properties getProperties() {
return properties;
}
public void setProperties(Properties properties) {
this.properties = properties;
}
public Set getAxes() {
return axes;
}
public void setAxes(Set axes) {
this.axes = axes;
}
@Override
public String toString() {
return "UserMeta{" +
"axes=" + axes.toString() + "\n" +
", properties=" + properties.toString() + "\n" +
", num=" + num + "\n" +
", user=" + user1 + "\n" +
", arrayList=" + arrayList.toString() + "\n" +
", map=" + map.toString() + "\n" +
", description='" + description + '\'' +
'}';
}
public Map<String, String> getMap() {
return map;
}
public void setMap(Map<String, String> map) {
this.map = map;
}
public User getUser1() {
return user1;
}
public void setUser1(User user1) {
this.user1 = user1;
}
}
spring配置文件
<?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"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
<!--for-test-->
<bean name="user" class="com.lq.play.model.User">
<property name="id" value="32324324"/>
<property name="username" value="lq"/>
<property name="password" value="123456"/>
<property name="salt" value="324343"/>
</bean>
<bean id="userMeta" name="userMeta" class="com.lq.play.model.UserMeta">
<!--int-->
<property name="num" value="1"/>
<!--string-->
<property name="description" value="描述。。。。。"/>
<!--bean-->
<property name="user1" ref="user"/>
<!--set-->
<property name="axes">
<set>
<value>普通字符串</value>
<bean class="com.lq.play.model.User"></bean>
<ref bean="user"/>
<array>
<value>tag1</value>
<set>
<value type="int">30</value>
</set>
</array>
</set>
</property>
<!--list-->
<property name="arrayList">
<list>
<value>tag1</value>
<value>tag2</value>
<value>tag3</value>
</list>
</property>
<!--map-->
<property name="map">
<map>
<entry key="key1" value="value1"/>
<entry key="key2" value="value2"/>
<entry key="key3" value="value3"/>
</map>
</property>
<!--property-->
<property name="properties">
<props>
<prop key="name">name1</prop>
<prop key="name">name1</prop>
</props>
</property>
</bean>
<!--<!– 自动扫描控制器 –>-->
<!--<context:component-scan base-package="com.lq.play.controller" use-default-filters="false">-->
<!--<!–<context:component-scan base-package="">–>-->
<!--<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>-->
<!--</context:component-scan>-->
<!--<!– 视图解析器 –>-->
<!--<bean id="internalResourceViewResolver"-->
<!--class="org.springframework.web.servlet.view.InternalResourceViewResolver">-->
<!--<property name="prefix" value="/WEB-INF/jsp" />-->
<!--<property name="suffix" value=".jsp" />-->
<!--</bean>-->
<!--<!– 控制器映射器和控制器适配器 –>-->
<!--<mvc:annotation-driven></mvc:annotation-driven>-->
<!--<!–<mvc:default-servlet-handler/>–>-->
<!--<!– 静态资源映射器 –>-->
<!--<mvc:resources mapping="/**" location="/WEB-INF/js/" />-->
<!--<mvc:resources mapping="/**" location="/WEB-INF/css/" />-->
</beans>
ApplicationTest测试类
package test;
import com.lq.play.model.User;
import com.lq.play.model.UserMeta;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.aspectj.EnableSpringConfigured;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
/**
* Created by liuqun on 2017/7/23.
*/
public class ApplicationTest {
public static void main(String[] args) throws Exception {
// ApplicationContext applicationContext = new ClassPathXmlApplicationContext("config/spring/spring-servlet.xml");
// User user = applicationContext.getBean("user", User.class);
// System.out.println(user.toString());
ApplicationContext applicationContext1 = new FileSystemXmlApplicationContext("classpath:config/spring/spring-servlet.xml");
UserMeta userMeta = applicationContext1.getBean("userMeta", UserMeta.class);
System.out.println(userMeta.toString());
}
}
输出:
UserMeta{axes=[普通字符串,
User{id=null, username='null', password='null', salt='null', locked=false},
User{id=32324324, username='lq', password='123456', salt='324343', locked=false}, [Ljava.lang.Object;@23e028a9]
, properties={name=name1}
, num=1
, user=User{id=32324324, username='lq', password='123456', salt='324343', locked=false}
, arrayList=[tag1, tag2, tag3]
, map={key1=value1, key2=value2, key3=value3}
, description='描述。。。。。'}
四,构造注入
UserMeta构造如下:
public UserMeta(Set axes, Properties properties, int num, User user1, List<String> arrayList, Map<String, String> map, String description) {
this.axes = axes;
this.properties = properties;
this.num = num;
this.user1 = user1;
this.arrayList = arrayList;
this.map = map;
this.description = description;
}
spring配置,其中有index、ref、value、type几个属性
<bean name="user" class="com.lq.play.model.User">
<property name="id" value="32324324"/>
<property name="username" value="lq"/>
<property name="password" value="123456"/>
<property name="salt" value="324343"/>
</bean>
<bean id="userMeta" name="userMeta" class="com.lq.play.model.UserMeta">
<!--int-->
<constructor-arg name="num" value="1" type="int" index="2"/>
<!--string-->
<constructor-arg name="description" value="描述。。。。。"/>
<!--bean-->
<constructor-arg name="user1" ref="user" index="3" type="com.lq.play.model.User" />
<!--set-->
<constructor-arg name="axes">
<set>
<value>普通字符串</value>
<bean class="com.lq.play.model.User"></bean>
<ref bean="user"/>
<array>
<value>tag1</value>
<set>
<value type="int">30</value>
</set>
</array>
</set>
</constructor-arg>
<!--list-->
<constructor-arg name="arrayList">
<list>
<value>tag1</value>
<value>tag2</value>
<value>tag3</value>
</list>
</constructor-arg>
<!--map-->
<constructor-arg name="map">
<map>
<entry key="key1" value="value1"/>
<entry key="key2" value="value2"/>
<entry key="key3" value="value3"/>
</map>
</constructor-arg>
<!--property-->
<constructor-arg name="properties">
<props>
<prop key="name">name1</prop>
<prop key="name">name1</prop>
</props>
</constructor-arg>
</bean>
运行结果跟设值注入是一样的