一、首先简单熟悉一下Spring框架:

                                       

简要说明:

IOC:相当于一个大的抽象工厂,通过依赖注入的方式,负责创建对象和管理关系(对象之间的依赖)、Hibernate的session、事务等的管理。

AOP:是一种面向切片的编程思想,使用类似jdk的动态代理的方式,来处理一些可以独立的服务,如,事务、filter等

DAO:jdbc做了一层封装,同时也有基于HIbernate的封装。

ORM:Hibernate是对JPA规范的一个实现,iBats是基于sql的一个映射器,TopLink是oracle对jdbc做的一个规范等等,Spring对这些框架做了集成。

WEB:Spring对诸如Struts(基于请求驱动)以及JSF(基于事件驱动)的框架做了集成。

Spring是一个主要管理业务处理对象的框架,其核心是IOC和AOP。


二、IOC(Inverse of Control):

在每个框架的中都有一个容器的概念,所谓的容器就是将常用的服务,封装起来,然后,用户只需要遵循一定的规则,就可以达到统一、灵活、安全、方便、快速的目的。

IOC是一个依赖注入DI(Dependence Injection)的方式达到控制反转目的的框架。

控制反转:的优势在于将服务交给容器。

我们对比一下由我们的应用程序负责服务(对象)定位:

public class UserManagerImpl implements UserManager {


	public void addUser(String username, String password) {
		
		//由我们的应用程序负责服务(对象)定位
		//UserDao userDao = new UserDao4MySqlImpl();
		UserDao userDao = new UserDao4OracleImpl();
		userDao.addUser(username, password);
	}


}

如果需要更换实现,如果使用应用程序的定位,我们还需要手动去修改程序,这是一件很糟糕的事情。

现在有了容器时候,这个定位就交给了容器,在程序中,只是一个变量的生命,没有实质的固定的实例化,这个实例化的过程放到了配置文件,框架在启动的时候,遵循一个规律,在对象使用之前,已经实例化,这样就达到了一个动态灵活的目的。

我们看一下,使用容器后的业务处理类(Manager)对数据访问层实现类(DAO)的代码:

public class UserManagerImpl implements UserManager {
	
	private UserDao userDao;
	
/*	public UserManagerImpl(UserDao userDao) {
		this.userDao = userDao;
	}*/
	
	public void addUser(String username, String password) {
		userDao.addUser(username, password);
	}
	public void setUserDao(UserDao userDao) {
		this.userDao = userDao;
	}
	

}

这里我们已经看不到实例化的对象了。接下来也正是IOC容器配置的使用。


三、使用容器注入对象:

1、框架搭建:

 1. 提供相关jar包:spring.jar(核心)、commons-logging.jar(不可少)、junit.jar(测试)、log4j-1.2.14.jar(记录日志)

 2. 提供配置文件:applicationContext.xml(注入的核心)、log4j.properties(日志相关)、放到src(Classpath)文件下

2、注入:DI

所谓的注入就是按照Spring的约束编写配置文件,这里只列出一些常用的配置方法,其他更多参见文章末尾的api文档下载链接。

1.使用构造函数的注入:

配合使用构造函数:

public class UserManagerImpl implements UserManager {
	
	private UserDao userDao;
	
	public UserManagerImpl(UserDao userDao) {
		this.userDao = userDao;
	}
	
	public void addUser(String username, String password) {
		userDao.addUser(username, password);
	}
	
	


}
applicationContext.xml中使用constructor-arg标签:

  <bean id="userManager" class="com.bjpowernode.spring.manager.UserManagerImpl">
  	
   <constructor-arg ref="userDao4Mysql"/> 
   	
  </bean>


2.成员变量方式的注入:

这里不需要提供关联类的构造函数,但需要提供set属性函数:

public class UserManagerImpl implements UserManager {
	
	private UserDao userDao;
	
	public void addUser(String username, String password) {
		userDao.addUser(username, password);
	}
	public void setUserDao(UserDao userDao) {
		this.userDao = userDao;
	}
	
}

applicationContext.xml使用property标签:

  <bean id="userManager" class="com.bjpowernode.spring.manager.UserManagerImpl">
  
   	<property name="userDao" ref="usrDao4Oracle" />
   	
  </bean>

两种方式的对比

使用构造函数注入,具有一定的局限性,如如果调用的类比较多,参数就比较多,这样处理起来不方便,另外,在一定程度上造成了侵入性,不是一种好的的做法,所以,建议使用属性注入的方式。


3.普通属性(包括集合)的注入:

使用容器,注入对象实质是将对象赋值放到了配置文件中,普通属性的注入和对象的注入的实质是一样的,达到的是一个在配置文件中赋值的目的。

要求注入的属性必须提供set方法,比较简单,列出代码即可明白:

提供待注入的类以及相关属性:

public class Bean1 {

	private String  strValue;
	
	private int  intValue;
	
	private String[] arrayValue;
	
	private  List list;
	
	private Set set;
	
	private Map map;
	
	
	public String getStrValue() {
		return strValue;
	}

	public void setStrValue(String strValue) {
		this.strValue = strValue;
	}

	public int getIntValue() {
		return intValue;
	}

	public void setIntValue(int intValue) {
		this.intValue = intValue;
	}

	public String[] getArrayValue() {
		return arrayValue;
	}

	public void setArrayValue(String[] arrayValue) {
		this.arrayValue = arrayValue;
	}

	public List getList() {
		return list;
	}

	public void setList(List list) {
		this.list = list;
	}

	public Set getSet() {
		return set;
	}

	public void setSet(Set set) {
		this.set = set;
	}

	public Map getMap() {
		return map;
	}

	public void setMap(Map map) {
		this.map = map;
	}
	
	
}

完整的配置文件:

<?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:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd" >

	<bean id="bean1" class="com.bjpowernode.spring.Bean1">
		<property name="strValue" value="ceshi"></property>
		<property name="intValue" value="123"></property>
		<property name="arrayValue">
			<list>
				<value>a</value>
				<value>b</value>
			</list>
		</property>

		<property name="list">
			<list>
				<value> A</value>
				<value> B</value>
			</list>
		</property>

		<property name="set">
			<set>
				<value>M</value>
				<value>N</value>
			</set>
		</property>

		<property name="map">
			<map>
				<entry key="k1" value="v1"></entry>
				<entry key="k2" value="v2"></entry>
			</map>
		</property>
		
	</bean>

	
</beans>


四、使用IOC的好处总结:

1、使用容器,控制反转,不再需要使用应用程序主动查找、定位、创建对象,这一切都交给容器统一管理。

2、大量减少了Factory和Singleton的数量,代码层次更加清晰。

3、IOC是一个轻量级的框架容器,具有pojo的优势,没有侵入性,没有对其他api的依赖,也不需要实现特殊接口。

4、减少了代码的耦合,将对象的赋值,放到了配置文件中,更容易处理变化。

上面就是SpringIOC容器基本的配置,更多详细配置,参见这里的api文档。

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐