Spring IOC

原创
2016/11/08 19:00
阅读数 128

2、IOC(Inversion of Control,控制倒转)

IoC 容器:最主要是完成了完成对象的创建和依赖的管理注入等等。

所谓控制反转,就是把原先我们代码里面需要实现的对象创建、依赖的代码,反转给容器来帮忙实现。那么必然的我们需要创建一个容器,同时需要一种描述来让容器知道需要创建的对象与对象的关系。这个描述最具体表现就是我们可配置的文件。

Action Service DAO

Service:

UserDao userDao = new UserDao(); -->意味着依赖于实现类,将来如果要更改实现类,在调用的地方需要全部修改。

使用Factory可以解决这一问题。

DI(Dependency Injection,依赖注入)来注入对象。

    2.1、Spring的对象类型:singleton(是单例)和prototype(是多例),默认是单例的对象

    使用范围:只要属性中没有需要修改的值(dao,service这两层的数据一般不会有相应的属性会修改)所
    以可以考虑用单例。

    如果属性中有需要修改的变量,如:action中会存储很多要操作的vo类,此时这个对象的状态会被修改,
    就要使用多例。

    2.2、依赖注入

    基本条件:所有的类都要被spring所管理才能进行依赖注入。

    有多种方式可以进行注入:

    1、使用set注入(最常用的方式)

    1.1、提供相应的要注入的类的setter

	private IUserDao userDao;

	public IUserDao getUserDao() {
		return userDao;
	}
	
	//提供要注入的类的set方法
	public void setUserDao(IUserDao userDao) {
		this.userDao = userDao;
	}

    1.2、在配置文件中注入

	<bean id="userDao" class="org.pm.spring.dao.UserDao"/>
	
	<bean id="userService" class="org.pm.spring.service.UserService">
		<!-- name中的值会在userService对象中setXX方法来注入,诸如:name="userDao" 
			在具体注入时会调用setUserDao(IUserDao userDao)来完成注入。 
			ref="userDao"表示是配置文件中的bean中所创建的DAO的id -->
		<property name="userDao" ref="userDao"></property>
	</bean>
	
	<!-- 对于UserAction而言,里面的属性的值的状态会根据不同的线程得到不同的值,
		所以应该使用多例 -->
	<bean id="userAction" class="org.pm.spring.action.UserAction" scope="prototype">
		<property name="userService" ref="userService"></property>
	</bean>

    2、基于构造函数的注入(了解)

	<!-- 以下是使用构造函数来注入,不常用,基本都是使用set方法注入 -->
	<bean id="userAction" class="org.pm.spring.action.UserAction" scope="prototype">
		<constructor-arg ref="userService"/>
	</bean>

2.3、属性注入和自动注入

    1、属性注入

	<!-- 创建了一个User对象user,id为1,username为悟空,如果要注入值不使用ref而是使用value -->
	<bean id="user" class="org.pm.spring.model.User">
		<property name="id" value="2"/>
		<property name="name" value="八戒"/>
	</bean>
	<!-- 对于UserAction而言,里面的属性的值的状态会根据不同的线程得到不同的值,
		所以应该使用多例 -->
	<bean id="userAction" class="org.pm.spring.action.UserAction" scope="prototype">
		<property name="userService" ref="userService"/>
        <!-- 引用了spring中定义的user对象 -->
		<property name="user" ref="user"/>
		<property name="id" value="12"/>
		<!-- 同样可以注入列表,但是也不常用 -->
		<property name="names">
			<list>
				<value>aaa</value>
				<value>bbb</value>
				<value>ccc</value>
			</list>
		</property>
	</bean>

    2、自动注入(一般不使用)

    2.1、byName是根据set的名称来注入,如果名称不对就无法注入

	<!-- autowire=byName表示会根据name来完成注入,
		byType表示根据类型注入 ,使用byType注入如果一个类中有两个同类型的对象就会抛出异常。
		所以在开发中一般都是使用byName,
		虽然自动注入可以减少配置,但是通过bean文件无法很好了解这个类的结构,所以不建议使用autowire -->
	<bean id="userService" class="org.pm.spring.service.UserService" autowire="byName">
		
	</bean>

2.2、byType表示是根据类型来注入,和名称无关,如果一个类中有两个相同类型的对象就无法注入

	<!-- autowire=byName表示会根据name来完成注入,
		byType表示根据类型注入 ,使用byType注入如果一个类中有两个同类型的对象就会抛出异常。
		所以在开发中一般都是使用byName,
		虽然自动注入可以减少配置,但是通过bean文件无法很好了解这个类的结构,所以不建议使用autowire -->
	<bean id="userService" class="org.pm.spring.service.UserService" autowire="byType">
	
	</bean>

如果要使用一般使用byName。

将autowire放置到bean上表示只是在这个bean中会自动注入。

放置到beans标签上所有的类都可以完成自动注入。

<?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" default-autowire="byName">

2.4、基于Annotation的注入

1、设置beans.xml的schema

<?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/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">
        
    <!-- 打开Spring的Annotation支持 -->
	<context:annotation-config/>
	<!-- 设定Spring去哪些包中找Annotation -->
	<context:component-scan base-package="org.pm.spring"/>
	
</beans>

2、在类上面设置

//等于完成了<bean id="userService" class="org.pm.spring.dao.UserService"/>
//在spring中创建这个bean,默认是byType,所以加上一个名称就会使用byName注入
@Component("userService") //公共的创建bean的Annotation
public class UserService implements IUserService {
	private IUserDao userDao;
	private IUserDao userJDBCDao;

	public IUserDao getUserDao() {
		return userDao;
	}
	
	//默认通过名称注入,在JSR330中提供了@Inject来注入
	@Resource
	public void setUserDao(IUserDao userDao) {
		this.userDao = userDao;
	}

3、spring3.0之后的Annotation建议

    由于开发中一般都是分为四层体系:data,dao,service,action,

    建议在dao层:

@Repository("userDao") //@Repository一般用于DAO的注入
public class UserDao implements IUserDao {

    service层:

@Service("userService") //业务层一般使用@Service
public class UserService implements IUserService {

    action层:

@Controller("userAction") //MVC的控制层一般使用@Controller
@Scope("prototype") //多实例
public class UserAction {

 

展开阅读全文
打赏
0
5 收藏
分享
加载中
更多评论
打赏
0 评论
5 收藏
0
分享
OSCHINA
登录后可查看更多优质内容
返回顶部
顶部