Spring之ioc

目录

一、spring是什么,它能够做什么?

二、 什么是控制反转(或依赖注入)?

案例:实现Spring的IoC做一个上传的功能,普通写法和spring写法的区别

(1)普通写法

(2)spring写法

3,Spring传参

 四、spring与tomcat的整合

1、监听器:SpringLoaderListener实现 ServletContextListener接口

2、web.xml中配置监听器

3、测试及结果


一、spring是什么,它能够做什么?

spring tool suite官方下载地址:http://spring.io/tools/sts/all

  1.Spring是一个开源框架,它由Rod Johnson创建。它是为了解决企业应用开发的复杂性而创建的。
  2.Spring使用基本的JavaBean来完成以前只可能由EJB完成的事情。
   然而,Spring的用途不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何   Java应用都可以从Spring中受益。
   目的:解决企业应用开发的复杂性
   功能:使用基本的JavaBean代替EJB,并提供了更多的企业应用功能
   范围:任何Java应用
   简单来说,Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。

spring是中间层框架、万能胶,将其他框架包裹进来

二、 什么是控制反转(或依赖注入)?

控制反转(IoC=Inversion of Control)IoC,用白话来讲,就是由容器控制程序之间的(依赖)关系,而非传统实现中,由程序代码直接操控。这也就是所谓“控制反转”的概念所在:(依赖)控制权由应用代码中转到了外部容器,控制权的转移,是所谓反转。
   IoC还有一个另外的名字:“依赖注入 (DI=Dependency Injection)”  ,即由容器动态将某种依赖关系注入到组件之中
 

案例:实现Spring的IoC做一个上传的功能,普通写法和spring写法的区别

假设做一个上传功能
现在提出整改要求:1,限定上传文件大小    2,限定上传文件类别

现在有几个版本的要求:
action1 不需要加限制        action2  需要加限制

假设你有开发一个游戏,原版本action1不需要加限制,当你开发出了一个新功能,需要更新版本action2,如果更新给游戏其他功能带来问题,我们需要要回到上一个版本,这是IOC的功能就体现出来了

总结:1.更新版本需要改动原有代码    2.相关调用此方法的模块伴随着巨大风险

代码演示如下:

使用的相关类:

接口

package com.ltf.ioc.biz;

public interface UserBiz {
	public void upload();
}

(1)普通写法

第一个版本(原始版本)写UserBiz.xml的实现类UserBizImpl1.java实现基础功能

package com.ltf.ioc.biz.impl;

import com.ltf.ioc.biz.UserBiz;

/**
 * 功能:上传功能
 * 提出整改
 * 1,限定上传文件大小  2.限定上传文件类别
 * 总结:
 * 1,更新版本需要改动原有代码
 * 2,相关调用此方法的模块伴随着巨大的风险
 * 
 *action1   需要加限制
 *action2   不需要加限制

 * @author zjjt
 *
 */
public class UserBizImpl1 implements UserBiz{

	@Override
	public void upload() {
		System.out.println("循规蹈矩的把功能开发出来");
	}

}

 第二个版本(更新后版本)写UserBiz.xml的实现类UserBizImpl2.java实现优化性能功能

package com.ltf.ioc.biz.impl;

import com.ltf.ioc.biz.UserBiz;

public class UserBizImpl2 implements UserBiz{

	@Override
	public void upload() {
		System.out.println("做条件判断加限定,文件太大了不能上传");
		System.out.println("循规蹈矩的把功能开发出来");
	}

}

假设有两个模块要使用(一个本模块,一个关联模块)

UserAction :

package com.ltf.ioc.web;

import com.ltf.ioc.biz.UserBiz;
import com.ltf.ioc.biz.impl.UserBizImpl1;

public class UserAction {
	private UserBiz userBiz = new UserBizImpl1();

	public void upload() {
		userBiz.upload();
	}

	public static void main(String[] args) {
		UserAction userAction = new UserAction();
		userAction.upload();
	}
}

PersonAction :

package com.ltf.ioc.web;

import com.ltf.ioc.biz.UserBiz;
import com.ltf.ioc.biz.impl.UserBizImpl2;

public class PersonAction {
	private UserBiz userBiz = new UserBizImpl2();

	public void upload() {
		userBiz.upload();
	}

	public static void main(String[] args) {
		PersonAction personAction = new PersonAction();
		personAction.upload();
	}
}

如果有100个需要整改模块,那就需要改100次原有代码(繁琐);

同时,相关调用此方法的模块伴随巨大的风险;

(2)spring写法

1,导入jar依赖(pom.xml文件)

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.ltf</groupId>
	<artifactId>spring01</artifactId>
	<packaging>war</packaging>
	<version>0.0.1-SNAPSHOT</version>
	<name>spring01 Maven Webapp</name>
	<url>http://maven.apache.org</url>
	<properties>
		<spring.version>5.0.1.RELEASE</spring.version>
		<javax.servlet.version>4.0.0</javax.servlet.version>
		<junit.version>4.12</junit.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>3.8.1</version>
			<scope>test</scope>
		</dependency>
		<!-- 2、导入spring依赖 -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-aspects</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<!-- 5.1、junit -->
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>${junit.version}</version>
			<scope>test</scope>
		</dependency>
		<!-- 5.2、servlet -->
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>javax.servlet-api</artifactId>
			<version>${javax.servlet.version}</version>
			<scope>provided</scope>
		</dependency>
	</dependencies>
	<build>
		<finalName>spring01</finalName>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.7.0</version>
				<configuration>
					<source>1.8</source>
					<target>1.8</target>
					<encoding>UTF-8</encoding>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>

2,resourse目录下导入xsd文件(spring-context.xml)

<?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: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/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<!-- 本文件中配置整个项目中所有的javabean,目的在于SPring的统一管理-->

</beans>

3,新建测试类对spring-context.xml进行建模

package com.ltf.ioc.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.ltf.ioc.web.PersonAction;

public class IocTest {
	public static void main(String[] args) {
		ApplicationContext applicationContext=new ClassPathXmlApplicationContext("/spring-context.xml");
//		Object bean = applicationContext.getBean("personAction");强转如下
		PersonAction personAction =(PersonAction) applicationContext.getBean("personAction");
		personAction.upload();
	}
}

4,修改action并进行配置

spring-context.xml中提供依赖propertyname属性PersonAction中用到的UserBiz赋值

<bean name="personActipon" class="com.ltf.ioc.web.PersonAction.java">
  <property name="userBiz" ref="userBiz2"></property>
 </bean>

同时需要修改 PersonAction,为UserBiz属性提供get set方法

package com.ltf.ioc.web;

import com.ltf.ioc.biz.UserBiz;

public class PersonAction {
	private UserBiz userBiz;
	
	public UserBiz getUserBiz() {
		return userBiz;
	}

	public void setUserBiz(UserBiz userBiz) {
		this.userBiz = userBiz;
	}

	public void upload() {
		userBiz.upload();
	}

	public static void main(String[] args) {
		PersonAction personAction = new PersonAction();
		personAction.upload();
	}
}

 这样private UserBiz userBizuserBiz 就和spring-context.xml中的相对应

5,IocTest类测试结果如下:

如果版本出现问题,要切回原来的版本,只需要修改ref的参数即可

 <bean name="personAction" class="com.ltf.ioc.web.PersonAction">
        <property name="userBiz" ref="userBiz1"></property>
    </bean>

UserAction、UserAction2、UserAction3  三个类是一样的,方便测试

package com.ltf.ioc.web;

import com.ltf.ioc.biz.UserBiz;
import com.ltf.ioc.biz.impl.UserBizImpl1;

public class UserAction {
    private UserBiz userBiz;

    public UserBiz getUserBiz() {
        return userBiz;
    }

    public void setUserBiz(UserBiz userBiz) {
        this.userBiz = userBiz;
    }

    public void upload() {
        userBiz.upload();
    }

    public static void main(String[] args) {
        UserAction userAction = new UserAction();
        userAction.upload();
    }
}

 配置spring-context.xml

    <bean name="userAction" class="com.ltf.ioc.web.UserAction">
        <property name="userBiz" ref="userBiz1"></property>
    </bean>
    <bean name="userAction2" class="com.ltf.ioc.web.UserAction2">
        <property name="userBiz" ref="userBiz1"></property>
    </bean>
    <bean name="userAction3" class="com.ltf.ioc.web.UserAction3">
        <property name="userBiz" ref="userBiz1"></property>
    </bean>

 IocTest类测试结果如下:又回到了第一个版本

 开发时一个接口一个实现类,不同模块不同需求时才会一个接口多个实现类

假如需要更新直接修改配置就可以了,不用修改原有代码,实现一次修改多次使用;

3,Spring传参

三种传参方式:

1.set传参

2.构造传参

3.自动装配(基本不用)

set传参

package com.ltf.ioc.web;

import java.util.List;

public class ParamAction {
	private int age;
	private String name;
	private List<String> hobby;

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public List<String> getHobby() {
		return hobby;
	}

	public void setHobby(List<String> hobby) {
		this.hobby = hobby;
	}

	public void execute() {
		System.out.println(this.age);
		System.out.println(this.name);
		System.out.println(this.hobby);

	}
}

    <bean name="ParamAction" class="com.ltf.ioc.web.ParamAction">
        <property name="name" value="sb"></property>
        <property name="age" value="20"></property>
        <property name="hobby">
            <list>
                <value>吃吃吃</value>
                <value>睡睡睡</value>
                <value>胖胖胖</value>
            </list>
        </property>
    </bean>

 

 构造传参

package com.ltf.ioc.web;

import java.util.List;

public class ParamAction {
	private int age;
	private String name;
	private List<String> hobby;

	public ParamAction() {
		super();
	}

	public ParamAction(int age, String name, List<String> hobby) {
		super();
		this.age = age;
		this.name = name;
		this.hobby = hobby;
	}

	public void execute() {
		System.out.println(this.age);
		System.out.println(this.name);
		System.out.println(this.hobby);

	}
}

<bean name="ParamAction" class="com.ltf.ioc.web.ParamAction">  
         
        <constructor-arg name="name" value="sb"></constructor-arg>
        <constructor-arg name="age" value="20"></constructor-arg>
        <constructor-arg name="hobby">
            <list>
                <value>吃吃吃</value>
                <value>睡睡睡</value>
                <value>胖胖胖</value>
            </list>
        </constructor-arg>
    </bean>

 四、spring与tomcat的整合

假如spring-context.xml中配置了几百个类,测试建模的时间过程非常久;

javabean每建一次模,时间就越久,性能就越差;

这行代码会执行很久,所以说这行代码在项目中只能执行一次,将他放到监听器中

建模存在代码性能问题,那么只能存在一次
通过监听器的方式,保障整个过程中只有一次建模

1、监听器:SpringLoaderListener实现 ServletContextListener接口

package com.ltf.ioc.listener;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringLoaderListenner implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        System.out.println("监听方法执行。。。。。。");
        ApplicationContext applicationContext=new ClassPathXmlApplicationContext("/spring-context.xml");
        sce.getServletContext().setAttribute("SpringContext", applicationContext);
    }
}

2、web.xml中配置监听器

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
    version="3.1">
  <display-name>Archetype Created Web Application</display-name>
<listener>
<listener-class>com.ltf.ioc.listener.SpringLoaderListerer</listener-class>
</listener>


</web-app>
 

3、测试及结果

①、测试UserServlet

package com.ltf.ioc.web;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

@WebServlet("/user")
public class UserServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ApplicationContext SpringContext = (ApplicationContext) req.getServletContext().getAttribute("SpringContext");
        ParamAction paramAction = (ParamAction) SpringContext.getBean("ParamAction");
        paramAction.execute();
    }
}
 

 ②、结果:监听器只会执行一次,结果可执行多次

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小宝的宝呢

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值