目录
1.1 什么是Spring?
Spring是一个开源框架,它由Rod Johnson创建。
它是为了解决企业应用开发的复杂性而创建的。
Spring使用基本的JavaBean来完成以前只可能由EJB完成的事情。
然而,Spring的用途不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何Java应用都可以从Spring中受益。
目的:解决企业应用开发的复杂性
功能:使用基本的JavaBean代替EJB,并提供了更多的企业应用功能
范围:任何Java应用
简单来说,Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。
Spring有很多模块,今天我们带来的是IOC模块:
IOC的两大特点就是:控制反转以及依赖注入。
控制反转就是: 将以前由程序员实例化对象/赋值的工作交给了Spring容器处理。
UserAction类:
- package com.leaf.web;
-
- import java.util.List;
-
- import com.leaf.ioc.biz.UserBiz;
-
- import impl.UserBizImpl2;
-
- /**
- * 用户模块
- * @author Leaf
- *
- * 依赖注入的三种方式:
- * 1、set注入
- * 2、构造注入
- * 3、自动装配
- * default-autowire="byName"
- * byName:是通过Spring管理的bean对象的id进行查找,如果找不到则注入失败,反之成功;
- * byType:是通过Spring管理的bean对象接口的实现类进行查找,如果没有、或有2个以上,则注入失败,反之成功。
- *
- * 2022年8月5日 下午2:40:54
- */
- public class UserAction {
-
- //private UserBiz ub = new UserBizImpl2();
- private UserBiz ub;
-
- public UserBiz getUb() {
- return ub;
- }
- public void setUb(UserBiz ub) {
- this.ub = ub;
- }
-
- /**
- * set注入
- */
- private String name;
- private int age;
- private List
hobby; -
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public int getAge() {
- return age;
- }
- public void setAge(int age) {
- this.age = age;
- }
- public List
getHobby() { - return hobby;
- }
- public void setHobby(List
hobby) { - this.hobby = hobby;
- }
-
- //调用查询用户数据的方法
- public void list() {
- System.out.println(name);
- System.out.println(age);
- System.out.println(hobby);
- ub.list();
- }
-
- }
OrderAction类:
- package com.leaf.web;
-
- import java.util.List;
-
- import com.leaf.ioc.biz.UserBiz;
-
- import impl.UserBizImpl1;
-
- /**
- * 订单模块
- * @author Leaf
- *
- * 2022年8月5日 下午2:40:31
- */
- public class OrderAction {
-
- //private UserBiz ub = new UserBizImpl1();
- private UserBiz ub;
-
- public UserBiz getUb() {
- return ub;
- }
- public void setUb(UserBiz ub) {
- this.ub = ub;
- }
-
- /**
- * 构造注入
- */
- private String name;
- private int age;
- private List
hobby; -
- public OrderAction() {
-
- }
- public OrderAction(String name, int age, List
hobby) { - this.name = name;
- this.age = age;
- this.hobby = hobby;
- }
-
- //调用查询用户数据的方法
- public void list() {
- System.out.println(name);
- System.out.println(age);
- System.out.println(hobby);
- ub.list();
- }
-
- }
还有我们的业务需求,接口类:UserBiz
- package com.leaf.ioc.biz;
-
- /**
- * 用户业务类
- * 需求:
- * 同时在用户模块、订单模块拿到所有用户数据
- *
- * 需求变更1:
- * 同时在用户模块、订单模块拿到所有用户数据,
- * 并且要求用户数据是已经通过年龄排序了的
- * 对应策略:修改userBiz中的list方法,添加排序功能
- *
- * 需求变更2:
- * 同时在用户模块、订单模块拿到所有用户数据,
- * 并且要求用户数据是已经通过注册时间点排序了的
- * 对应策略:修改userBiz中的list方法,添加排序功能,按照时间点排序
- *
- * ...
- * 总结:
- * 最原始:频繁修改业务层Biz层代码
- * 多实现:凡是涉及业务层调用的地方,都需要修改代码
- *
- * @author Leaf
- *
- * 2022年8月5日 下午2:31:03
- */
- public interface UserBiz {
-
- /**
- * 用户查询
- */
- public void list();
-
- }
上面代码也就包括了我依赖注入的三种方式:分别在UserAction&&OrderActio里面;
接着我们只需要在Spring的配置文件spring-context.xml里面配置好就行啦:
spring-context.xml:
- <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">
-
-
-
-
- <bean class="impl.UserBizImpl1" id="userBiz" scope="singleton">bean>
-
-
-
- <bean class="com.leaf.web.UserAction" id="userAction">
- <property name="ub" ref="userBiz">property>
- <property name="name" value="Leaf">property>
- <property name="age" value="18">property>
- <property name="hobby">
- <list>
- <value>篮球value>
- <value>摄影value>
- <value>画画value>
- list>
- property>
- bean>
-
-
- <bean class="com.leaf.web.OrderAction" id="orderAction">
- <property name="ub" ref="userBiz">property>
- <constructor-arg name="name" value="癫癫">constructor-arg>
- <constructor-arg name="age" value="19">constructor-arg>
- <constructor-arg name="hobby">
- <list>
- <value>篮球value>
- <value>摄影value>
- <value>画画value>
- list>
- constructor-arg>
- bean>
-
- beans>
然后我们建立一个测试类:Demo1
- package com.leaf.ioc;
-
- import org.springframework.context.support.ClassPathXmlApplicationContext;
-
- import com.leaf.web.OrderAction;
- import com.leaf.web.UserAction;
-
- /**
- * 建模
- * 1、对spring框架的配置文件进行建模,
- * 建模之后,spring-context.xml中所有的javabean信息都会加载进spring容器的上下文中
- * 2、上下文中就包含了spring-context.xml 中的所有对象
- * @author Leaf
- *
- * IOC的特点:依赖注入 控制反转
- * 1、控制反转:指的是将创建对象的权利反转给spring容器来完成
- * 2、IOC的主要作用就是管理整个项目的javabean,依靠依赖注入、控制反转的特点进行管理
- *
- * 2022年8月5日 下午3:05:42
- */
- public class Demo1 {
-
- public static void main(String[] args) {
-
- //拿到spring的上下文
- ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("/spring-context.xml");
- UserAction userAction = (UserAction) context.getBean("userAction");
-
- userAction.list();
-
- //拿到javabean对象
- OrderAction orderAction = (OrderAction) context.getBean("orderAction");
-
- //调用方法
- orderAction.list();
-
- }
-
- }
然后运行测试:
最后,我们还需要将Spring与Web端进行一个整合;
原因和思路都写在下面这个测试类里面了:
- package com.leaf.ioc;
-
- import java.io.IOException;
-
- import javax.servlet.ServletException;
- import javax.servlet.ServletRequest;
- import javax.servlet.ServletResponse;
- import javax.servlet.annotation.WebServlet;
- import javax.servlet.http.HttpServlet;
-
- import org.springframework.context.support.ClassPathXmlApplicationContext;
-
- import com.leaf.web.UserAction;
-
- /**
- * Spring与Web容器的整合原理
- * Why:建模的过程是十分耗时的
- * How:
- * 解决问题:
- * 1、建模必不可少
- * 2、建模要保障只执行一次
- * 3、建模后期望在每一个servlet都能拿到Spring的上下文对象ClassPathXmlApplicationContext;
- * 怎么解决:
- * 1、监听器的初始化方法
- * 2、Spring上下文 要 存放在 tomcat上下文中
- *
- * @author Leaf
- *
- * 2022年8月5日 下午4:33:15
- */
-
- @WebServlet("/springDemo")
- public class DemoServlet extends HttpServlet {
-
- @Override
- public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
- //拿到spring的上下文
- //ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("/spring-context.xml");
- ClassPathXmlApplicationContext context = (ClassPathXmlApplicationContext) req.getServletContext().getAttribute("springContext");
- //拿到javabean对象
- UserAction userAction = (UserAction) context.getBean("userAction");
- //调用方法
- userAction.list();
- }
-
- }
建立的servlet监听器:SpringLoadListener
- package com.leaf.ioc.listener;
-
- import javax.servlet.ServletContext;
- import javax.servlet.ServletContextEvent;
- import javax.servlet.ServletContextListener;
-
- import org.springframework.context.support.ClassPathXmlApplicationContext;
-
- import com.leaf.web.UserAction;
-
- /**
- * servlet上下文的监听器
- * @author Leaf
- *
- * 2022年8月5日 下午4:40:08
- */
- public class SpringLoadListener implements ServletContextListener{
-
- @Override
- public void contextInitialized(ServletContextEvent sce) {
- System.out.println("初始化...");
- //拿到servlet上下文
- ServletContext servletContext = sce.getServletContext();
- //拿到spring配置文件名
- String springConfigLocation = servletContext.getInitParameter("springConfigLocation");
- //拿到spring的上下文
- ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("/spring-context.xml");
- //将Spring上下文保存到tomcat上下文中
- servletContext.setAttribute("springContext", context);
- }
-
- }
最后我们运行测试一下:

OK啦,我们下期再见!!!