• Spring(ioc)


    一、Spring简介

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

    二、ioc依赖注入三种方式

    准备工作

    我们最开始要将我们的Spring对象导入到src/main/resources目录中
    然后我们的所有类都配置到bean对象中
    案例:
    一个接口,被两个实现类实现
    接口:UserBiz.java 实现类:UserBizImpl1.java UserBizImpl2.java
    两个业务处理层:OrderAction.java UserAction.java
    所有我们要配置五个bean对象到我们Spring配置文件中如:
    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">
    	
    	<!-- IOC的主要作用(管理整个项目的javaBean):依赖注入、控制反转的特点进行管理  -->
    		
    	<!-- 将所有类配置到bean -->
    	 <bean class="com.xlb.biz.UserBizImpl2" id="userBiz1"></bean> 
    	<bean class="com.xlb.biz.UserBizImpl1" id="userBiz"></bean>
    	<bean class="com.xlb.biz.UserBizImpl2" id="userBiz1"></bean>
    	<bean class="com.xlb.web.UserAction" id="userAction"></bean>
    	<bean class="com.xlb.web.OrderAction" id="orderAction"></bean>
    </beans>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    两个实现类UserBizImpl1.java

    package com.xlb.biz;
    
    public class UserBizImpl1 implements UserBiz{
    
    	@Override
    	public void list() {
    		System.out.println("用户查询数据,按照年龄排序");
    	}
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    UserBizImpl2.java

    package com.xlb.biz;
    
    public class UserBizImpl2 implements UserBiz{
    
    	@Override
    	public void list() {
    		System.out.println("查询用户数据,按照入职时间排序。。。。");
    	}
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    接口UserBiz.java

    package com.xlb.biz;
    
    /**
     * 用户业务类
     * @author Administrator
     *
     */
    public interface UserBiz {
    	/**
    	 * 用户查询
    	 */
    	void list();
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    1、set注入

    首先我们在UserAction业务处理层定于三个变量,然后我们在在配置文件中配置

    package com.xlb.web;
    
    import java.util.List;
    
    import com.xlb.biz.UserBiz;
    import com.xlb.biz.UserBizImpl1;
    
    /**
     * 
     * 
     * 
     */
    public class UserAction {
    	//private UserBiz userBiz = new UserBizImpl1();
    	
    	private UserBiz userBiz1;
    	
    	public UserBiz getUserBiz() {
    		return userBiz1;
    	}
    
    	public void setUserBiz(UserBiz userBiz1) {
    		this.userBiz1 = userBiz1;
    	}
    
    	private String name;
    	private int age;
    	private List<String> like;
    	
    	
    	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<String> getLike() {
    		return like;
    	}
    
    	public void setLike(List<String> like) {
    		this.like = like;
    	}
    
    	public void list() {
    		System.out.println(name);
    		System.out.println(age);
    		System.out.println(like);
    		userBiz1.list();
    	}
    	
    	
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64

    配置文件中配置属性:

    <bean class="com.xlb.web.UserAction" id="userAction">
    		<property name="userBiz" ref="userBiz"></property>
    		<property name="age" value="12"></property>
    		<property name="name" value="zhangsan"></property>
    		<property name="like">
    			<list>
    				<value>篮球</value>
    				<value>rep</value>
    				<value>鸡哥</value>
    			</list>
    		</property>
    	</bean>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    <bean class="com.xlb.biz.UserBizImpl1" id="userBiz"></bean>
    
    • 1

    然后写一个实现类Demo1.java
    步骤:

    1、对Spring框架的配置文件进行建模,建模之后spring-context.xml中所有的javabean信息都会
    加载进Spring 容器的上下文中
    2、上下文中就包含了spring-context.xml 中所有对象

    package com.xlb.ioc.demo;
    
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import com.xlb.web.OrderAction;
    import com.xlb.web.UserAction;
    
    /**
     * @author Administrator
     *
     * IOC的特点--什么叫控制反转
     * 指的是将创建对象的权利反转给Spring容器来完成
     *
     */
    public class Demo1 {
    	@SuppressWarnings("resource")
    	public static void main(String[] args) {
    		//建模
    		//1、spring-context.xml模型对象
    		ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("/spring-context.xml");
    		//拿到UserAction
    		UserAction userAction = (UserAction)context.getBean("userAction");
    		//调用方法
    		userAction.list();
    
    	}
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    结果:
    在这里插入图片描述

    2、构造注入

    构造注入姆以至于就是我们通过构造方法来给其实现赋值
    案例:我们在OrderAction中建立三个变量,给其一个空的构造方法和全参数的构造方法
    OrderAction.java

    package com.xlb.web;
    
    import java.util.List;
    
    import com.xlb.biz.UserBiz;
    import com.xlb.biz.UserBizImpl1;
    
    /**
     * 业务处理类1
     * @author Administrator
     *
     */
    public class OrderAction {
    	
    	//private UserBiz userBiz = new UserBizImpl1();
    	
    	private UserBiz userBiz;
    	
    	public UserBiz getUserBiz() {
    		return userBiz;
    	}
    
    	public void setUserBiz(UserBiz userBiz) {
    		this.userBiz = userBiz;
    	}
    	
    	
    	private String name;
    	private int age;
    	private List<String> like;
    	
    	//通过一个空的构造器和一个全参的构造器
    	public OrderAction() {
    		// TODO Auto-generated constructor stub
    	}
    
    	public OrderAction(String name, int age, List<String> like) {
    		super();
    		this.name = name;
    		this.age = age;
    		this.like = like;
    	}
    	
    	
    	
    	public void list() {
    		System.out.println(name);
    		System.out.println(age);
    		System.out.println(like);
    		userBiz.list();
    	}
    	
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54

    然后我们在去配置文件中配置:

    <!-- 构造注入 -->
    	<bean class="com.xlb.web.OrderAction" id="orderAction">
    		<property name="userBiz" ref="userBiz"></property>
    		<constructor-arg name="age" value="12"></constructor-arg>
    		<constructor-arg name="name" value="zhangsan"></constructor-arg>
    		<constructor-arg name="like">
    			<list>
    				<value>测试类</value>
    				<value>构造</value>
    				<value>注入</value>
    			</list>
    		</constructor-arg>
    	</bean>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    在去测试类调用:

    public class Demo1 {
    	@SuppressWarnings("resource")
    	public static void main(String[] args) {
    		//建模
    		//1、spring-context.xml模型对象
    		ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("/spring-context.xml");
    		OrderAction orderAction = (OrderAction)context.getBean("orderAction");
    		//调用方法
    		orderAction.list();
    		
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    结果
    在这里插入图片描述

    3、自动装配

    3.1、byName

    default-autowire=“byName”
    byName:是通过Spring管理的bin对象的ID进行查找,如果找不到则注入失败,反之成功

    当我们在项目配置中属性把对象注释,在运行那么项目就会报错

    在这里插入图片描述
    错误:
    在这里插入图片描述

    这个时候只需要我们去配置文件中加入属性 default-autowire=“byName”
    那么结果就又可以出现
    在这里插入图片描述
    在这里插入图片描述
    那么如果我们修改了一下工具类的属性名,那么该项目还是会报错,我们把UserAction.java中的userBiz修改成userBiz1

    package com.xlb.web;
    
    import java.util.List;
    
    import com.xlb.biz.UserBiz;
    import com.xlb.biz.UserBizImpl1;
    
    /**
     * 业务处理类2
     * 需求:
     * 	同时在用户模块、订单模块拿到所有的用户数据
     * 
     * 需求变更1:
     * 	同时在用户模块、订单模块拿到所有的用户数据,并且要求用户数据以及根据年龄排序
     * 	对应策略:修改userBiz中的list方法,添加排序功能,按照年龄排序
     * 
     * 需求变更2:
     *	同时在用户模块、订单模块拿到所有的用户数据,并且要求用户数据已经注册的时间点排序的
     *	 对应策略:修改userBiz中的list方法,添加排序功能,按照时间点排序
     * 
     * 。。。。。。
     * 总结:
     *	    最原始的方法:频繁修改业务层biz层代码
     *	   多实现方法(一个接口多实现):凡是涉及到 用户业务层调用方法的地方,都需要修改代码
     * 
     * @author Administrator
     *
     *
     * 依赖注入的三种方式
     * 1.set注入
     * 2.构造注入
     * 3.自动装配
     * 	   default-autowire="byName" 
     * 	   byName:是通过Spring管理的bin对象的ID进行查找,如果找不到则注入失败,反之成功
     * 	   default-autowire="byType" 	   
     *     byType:根据Spring管理的bean对象接口实现类进行查找;如果没有或2个以上,则注入失败,反之成功
     * 
     */
    public class UserAction {
    	//private UserBiz userBiz = new UserBizImpl1();
    	
    	private UserBiz userBiz1;
    	
    	
    
    	public UserBiz getUserBiz1() {
    		return userBiz1;
    	}
    
    	public void setUserBiz1(UserBiz userBiz1) {
    		this.userBiz1 = userBiz1;
    	}
    
    	private String name;
    	private int age;
    	private List<String> like;
    	
    	
    	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<String> getLike() {
    		return like;
    	}
    
    	public void setLike(List<String> like) {
    		this.like = like;
    	}
    
    	public void list() {
    		System.out.println(name);
    		System.out.println(age);
    		System.out.println(like);
    		userBiz1.list();
    	}
    	
    	
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92

    那么就会报错,这个时候我们只需要在加一个《bean》标签配置一下userbiz1
    在这里插入图片描述

    <bean class="com.xlb.biz.UserBizImpl2" id="userBiz1"></bean>
    	<bean class="com.xlb.biz.UserBizImpl1" id="userBiz"></bean>
    
    • 1
    • 2

    结果:
    在这里插入图片描述

    3.2、byType

    default-autowire=“byType”
    byType:根据Spring管理的bean对象接口实现类进行查找;如果没有或2个以上,则注入失败,反之成功

    这个就是指看是否能找到该接口,因为本项目两个类都是实现一个接口,所有可以运行,但是要注意一点,bean对象接口配置只能配置一个否则会报错
    配置两个接口:

    <bean class="com.xlb.biz.UserBizImpl2" id="userBiz1"></bean>
    	<bean class="com.xlb.biz.UserBizImpl1" id="userBiz"></bean>
    
    • 1
    • 2

    然后再加入 default-autowire=“byType”
    在这里插入图片描述

    那么就会报错
    在这里插入图片描述
    我们删除一个
    在这里插入图片描述

    三、Spring与web容器整合

    为了解决建模的繁琐性,提高效率,所有我们要把Spring和web容器进行整合

    Spring与web容器的整合原理
    why:建模的过程十分耗时的
    how:
    解决问题:
    1.建模比不可少
    2.建模要保障只执行一次
    3.建模后期望在每一个servlet都能够拿到Spring的上下文对象ClassPathXmlApplicationContext
    how:
    1.监听器(里面初始化只执行一次)
    2.Spring的上下文要存放在Tomcat上下文中

    我们先建一个类实现监听器:SpringLoadListener.java
    然后初始化方法contextInitialized
    在拿到Tomcat上下文
    将Spring上下文保存到Tomcat上下文中

    package com.xlb.biz.ioc.listener;
    
    import javax.servlet.ServletContext;
    import javax.servlet.ServletContextEvent;
    import javax.servlet.ServletContextListener;
    
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import com.xlb.web.UserAction;
    
    /**
     * 1.实现监听器
     * 2.初始化方法contextInitialized
     * 3.拿到Tomcat上下文
     * 2.将Spring上下文保存到Tomcat上下文中
     * 
     * @author Administrator
     *
     */
    public class SpringLoadListener implements ServletContextListener{
    
    	@Override
    	public void contextInitialized(ServletContextEvent sce) {
    		System.out.println("初始化");
    		ServletContext servletContext = sce.getServletContext();
    		//自定义配置文件
    		String aa = servletContext.getInitParameter("applicationContext.xml");
    		System.out.println(aa+"///拿到了自定义配置文件");
    		//拿到Spring上下文(包含所有javabean)
    		ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("/spring-context.xml");
    		//将Spring上下文保存到Tomcat上下文中
    		//applicationContext.xml
    		servletContext.setAttribute("springContext", context);
    		
    	}
    	
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    然后我们配置到web服务器上,顺便把定义项目名也配置了

    <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>
    	
      <context-param>
      	<param-name>springconfiglocation</param-name>
     	<param-value>/applicationContext.xml</param-value>
      </context-param>
    	
      <listener>
      	<listener-class>com.xlb.biz.ioc.listener.SpringLoadListener</listener-class>
      </listener>
    	
    </web-app>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    然后我们写一个实现类web层DemoServlet.java

    package com.xlb.ioc.demo;
    
    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.xlb.web.UserAction;
    
    /**
     * Spring与web容器的整合原理
     * why:建模的过程十分耗时的
     * how:
     * 	  解决问题:
     * 		1.建模比不可少
     * 		2.建模要保障只执行一次
     * 		3.建模后期望在每一个servlet都能够拿到Spring的上下文对象ClassPathXmlApplicationContext
     *
     *	how:
     *	  1.监听器(里面初始化只执行一次)
     *	  2.Spring的上下文要存放在Tomcat上下文中
     *    
     * @author Administrator
     *
     */
    @WebServlet("/springDemo")
    public class DemoServlet extends HttpServlet{
    
    	@Override
    	public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
    		//建模
    		//1、spring-context.xml模型对象
    		//ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("/spring-context.xml");
    		ClassPathXmlApplicationContext context = (ClassPathXmlApplicationContext)req.getServletContext().getAttribute("springContext");
    		//拿到UserAction
    		UserAction userAction = (UserAction)context.getBean("userAction");
    		//调用方法
    		userAction.list();
    	}
    	
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    结果:
    在这里插入图片描述

  • 相关阅读:
    RKMEDIA使用简介
    安卓恶意应用识别(二)(安卓APK反编译)
    Java类的继承
    【MySQL】专栏合集,从基础概念到调优
    C生万物之函数
    如何用GPT进行课题申报,论文选题及实验方案设计?
    【JavaScript】一文了解JS的闭包
    Python-Flask 蓝图以及钩子函数(5)
    Bootstrap5 表单
    【生物素叠氮化物|cas:908007-17-0】价格_厂家
  • 原文地址:https://blog.csdn.net/qq_63531917/article/details/126177187