现在的位置: 首页 > 综合 > 正文

轻松理解Spring的核心IoC

2013年09月18日 ⁄ 综合 ⁄ 共 3217字 ⁄ 字号 评论关闭

        一说起Spring,都说他最核心的部分就是IoC(Inversion of Control)——控制反转。那么到底什么是控制反转呢,简单的理解就是不用你自己去new一个对象或是根据一个名字向某个地方要对象(后者已经用了IoC单并不彻底),容器会自动给你所要的东西

        new对象,需要你自己知道是什么类,而根据名字向容器要对象也需要你知道配置情况,前者完全没有依赖反转,因为需要什么类都是由程序自己决定的。后者已经实现了控制反转,因为只需要配置到Spring的配置文件中,在程序中只需要根据配置的名称来选择即可,具体用那个,是在配置中的。

        但是上面两种情况都不是容器给你,都需要某种程度上的“要”。

        下面通过Spring和Struts来说明一下容器的“给”:

        Struts和Spring集成,如果想让Spring对Action进行注入,那么就必须使得Action是有Spring来创建的,只有这样,Action才能够被容器来管理,里面的对象才能够被容器注入。

        上面所说的事情呢,举个喝水的例子吧:

        new:你想喝水,那么你需要自己用壶接水,然后烧开,然后自己倒到杯子里面。

        向容器要:想喝水了,向别人说一下,我想和谁,于是乎别人就帮你倒了一杯水(好懒啊。。。)

        容器给:你把空杯子(接口)放到那,当你拿起杯子的时候,发现有人默默的给你倒好了水(好洋气啊。。)

        上面的三个例子只有自己new是没有用IoC的,后两者都用了IoC,只是程度深浅而已,但是推荐使用第三者。

那么用了Spring到底有什么好处呢?

        1.我们不再查找、定位、创建和管理对象之间的关系了,都交给了IoC容器来管理,使得代码层次更加清晰

        2.Spring的IoC容器是一个轻量级的容器,没有侵入性,不需要依赖容器的API,也不需要实现特殊接口

        3.会使框架工作的更好

        4.提供了AOP声明式服务能力,可以针对POJO提供声明式服务能力

        5.对于资源不再负责开启和关闭,完全由Spring来管理

        6.鼓励面向接口编程

        7.减少了代码中的耦合,将耦合推迟到了配置文件中,发生了变化也更容易控制

那么下面根据一段代码来看一下Spring到底是如何管理Struts中的Action以及业务逻辑层的注入吧

Web.xml

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  	<context-param>
  		<param-name>contextConfigLocation</param-name>
  		<!--声明spring的配置文件-->
  		<param-value>classpath:applicationContext-beans.xml</param-value>
  	</context-param>
  	
  	<!-- 配置Struts -->
  	<filter>
        <filter-name>struts2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    
    <!-- 配置Spring -->
    <listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>
</web-app>

Struts.xml

<struts>
	<!-- 声明Action是有Spring来管理的 -->
	<constant name="struts.objectFactory" value="spring"></constant>
	
	<!-- 声明登陆的Action -->
	<package name="textLogin" namespace="/" extends="struts-default">
		<!-- 这里的class声明的类是由spring来创建,达到了Action由Spring管理的目的 -->
		<action name="login" class="loginAction">
			<result name="success">success.jsp</result>
			<result name="error" type="redirect">error.jsp</result>
		</action>
	</package>
</struts>

applicationContext-beans.xml(Spring的配置文件)

<bean name="loginService" class="com.jianxin.struts2.LoginServiceImpl" />
	<bean name="loginAction" class="com.jianxin.struts2.LoginAction">
		<property name="loginService" ref="loginService" />
	</bean>

LoginAction

public class LoginAction extends ActionSupport {

	private String name;
	private String 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;
	}
	private LoginService loginService;
	public LoginService getLoginService() {
		return loginService;
	}
	public void setLoginService(LoginService loginService) {
		this.loginService = loginService;
	}

	@Override
	public String execute() throws Exception {
		String result;
		if(loginService.Login(name, password)){
			System.out.println("登录成功");
			result="success";
		} else {
			System.out.println("登录失败");
			result="error";
		}
		
		return result;
	}
}

        接口、实现类我就不贴了,自己随便写个就行了,至此可以从Action中看到,只声明了一下接口,并没有具体的实例化,这就是IoC容器的功劳,容器管理对象实例化的工作,更好的支持了面向接口的编程。



抱歉!评论已关闭.