spring之ioc

Posted liuwenwu9527

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring之ioc相关的知识,希望对你有一定的参考价值。

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

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

使用spring框架 先导入依赖

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.lww</groupId>
  <artifactId>T224_spring</artifactId>
  <packaging>war</packaging>
  <version>0.0.1-SNAPSHOT</version>
  <name>T224_spring 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>
    <!-- 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>T224_spring</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>

写一个接口 定义一个方法

UserBiz:

package com.liuwenwu.ioc.biz;
/**
 * 需求:
 *       上传文件需求
 *         完成的思路:完成功能就好   文件上传就行
 *         客户使用的时候:嫌弃上传的事件过长,要求优化
 *         由于某程序员的失误,改动的代码影响了其他模块的正常使用 
 * 
 *         客户:两头利害取其轻,情愿回退上一个版本
 *         
 * @author ASUS
 *
 */
public interface UserBiz 

    public void read();

两个实现类来实现接口:

UserBizImpl1:

package com.liuwenwu.ioc.biz.impl;

import com.liuwenwu.ioc.biz.UserBiz;

public class UserBizImpl1 implements UserBiz

    @Override
    public void read() 
        System.out.println("死记硬背");
        
    

UserBizImpl2:

package com.liuwenwu.ioc.biz.impl;

import com.liuwenwu.ioc.biz.UserBiz;

public class UserBizImpl2 implements UserBiz

    @Override
    public void read() 
        System.out.println("边学习边记笔记,最后举一反三");
    

spring管理Bean的方式(注入方式)
  set注入
    基本数据类型
    引用数据类型

UserAction定义属性,提供set方法

package com.liuwenwu.ioc.web;

import java.util.ArrayList;
import java.util.List;

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

/**
 * 弊端:
 *      当需求变化非常快的时候,不便于维护,因为维护的权利是属于程序员的
 *      
 *      spring的ioc就是解决这一问题的
 *         将维护代码的权利由程序员转交给spring容器来完成
 * 
 * 1、spring管理Bean的方式(注入方式)
 *       set注入
 *             基本数据类型
 *             引用数据类型
 *           构造注入
 *           自动装配
 *         
 * @author ASUS
 *
 */
public class UserAction 
//    实际开发中可能不止一个action实现这个接口 
//    private UserBiz userBiz =new UserBizImpl1();
    private UserBiz userBiz;
    private int uid;
    private String uname;
    private List<String> hobby=new ArrayList<String>();
    
    
    //提供set方法
//    public void setUid(int uid) 
//        this.uid = uid;
//    
//
//    public void setUname(String uname) 
//        this.uname = uname;
//    

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

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


    //    提供构造方法
    public UserAction(int uid, String uname) 
        super();
        this.uid = uid;
        this.uname = uname;
    
    
    
    public UserAction() 
    super();
    
    

    /**
     * set注入
     */
    public void test1() 
        System.out.println("uid:"+this.uid);
        System.out.println("uname:"+this.uname);
        System.out.println("hobby:"+this.hobby);
    
    


    /**
     * 构造注入
     */
    public void test2() 
        
    
    
    /**
     * 测试注入引用类型
     */

    public void test3() 
        userBiz.read();
    
    

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">
        
    <!-- id是唯一的 -->
    <bean id="userBiz" class="com.liuwenwu.ioc.biz.impl.UserBizImpl2"></bean>
    <!-- 管理多个  实现同一个接口-->
    <!-- <bean id="userBiz2" class="com.liuwenwu.ioc.biz.impl.UserBizImpl1"></bean> -->
    <bean id="userAction" class="com.liuwenwu.ioc.web.UserAction">
        <!-- set注入 -->
        <!-- <property name="uid" value="22"></property> -->
        <!-- <property name="uname" value="zs"></property> -->
        <property name="userBiz" ref="userBiz"></property> 
        <!-- 构造方法注入 -->
        <constructor-arg name="uid" value="22"></constructor-arg>
        <constructor-arg name="uname" value="zs"></constructor-arg>
        <property name="hobby">
            <list>
                <value>篮球</value>
                <value>RAP</value>
                <value>玩蛇</value>
            </list>
        </property>
    </bean>
</beans>

模拟浏览器发请求请求后台 Demo1:

package com.liuwenwu.ioc.test;

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

import com.liuwenwu.ioc.web.UserAction;

/**
 * 模拟浏览器发请求请求后台
 * @author ASUS
 *
 */
public class Demo1 
    public static void main(String[] args) 
//        UserAction userAction =new UserAction();
//        userAction.test1();
        
//        从spring获取
        ApplicationContext context=new ClassPathXmlApplicationContext("/spring-context.xml");
        UserAction bean = (UserAction) context.getBean("userAction");
//        bean.test1();
        bean.test3();
        
    

技术图片

构造方法注入 提供构造方法

    //    提供构造方法
    public UserAction(int uid, String uname) 
        super();
        this.uid = uid;
        this.uname = uname;
    
    
    
    public UserAction() 
    super();
    
    

spring-context.xml中配置

 <!-- 构造方法注入 -->
<constructor-arg name="uid" value="22"></constructor-arg>
<constructor-arg name="uname" value="zs"></constructor-arg>

set注入引用数据类型

private UserBiz userBiz;
<!-- 引用一个bean文件  把实体类注入接口-->
    <bean id="userBiz" class="com.liuwenwu.ioc.biz.impl.UserBizImpl2"></bean>
<!-- 引用类型注入 -->
    <property name="userBiz" ref="userBiz"></property> 

spring自动装配:

default-autowire="byType" 根据类型装配 如果多个类实现一个接口 就会报错

default-autowire="byName" 根据名字装配  用的多

 

将spring的上下文交给Tomcat上下文进行管理

SpringLoadListener:

package com.liuwenwu.ioc.test;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;

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

/**
 * 2、如何将spring的上下文交给Tomcat上下文进行管理
 *      首先spring上下文为什么交给tomca?
 *      分析:目前工程中所用javabean都交给了spring进行管理,那么浏览器发送请求
 *          请求的是Tomcat,由Tomcat来处理请求,Tomcat处理请求一般来说都要访问数据库
 *          数据库是由dao层访问的,dao层的实体类又是交给了spring是上下文管理,那就意味着
 *          Tomcat要处理请求,必须拿到spring的上下文,才能够拿到dao层的javabean
 * @author ASUS
 *
 */
//监听器
@WebListener
public class SpringLoadListener implements ServletContextListener 
//    配置文件地址
    private String springXmlLocation="";
    
    //重写
    @Override
//    Tomcat启动就会加载
    public void contextInitialized(ServletContextEvent sce) 
        System.out.println("监听了Tomcat的启动...");
//        获取Tomcat上下文
        ServletContext servletContext = sce.getServletContext();
        springXmlLocation=servletContext.getInitParameter("springXmlLocation");
        if(springXmlLocation==null ||"".equals(springXmlLocation)) 
            springXmlLocation="spring-context.xml";
        
        System.out.println("springXmlLocation"+springXmlLocation);
//        spring上下文
        ApplicationContext springContext=new ClassPathXmlApplicationContext(springXmlLocation);
//        将spring上下文交给Tomcat上下文
        servletContext.setAttribute("SPRING_CONTEXT_KEY", springContext);
    
    

UserServlet:

package com.liuwenwu.ioc.test;

import java.io.IOException;

import javax.servlet.ServletContext;
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 com.liuwenwu.ioc.web.UserAction;

@WebServlet("/user")
public class UserServlet extends HttpServlet 

    private static final long serialVersionUID = 3011793850996016507L;
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException 
        // TODO Auto-generated method stub
        doPost(req, resp);
    
    
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException 
//        拿到上下文
        ServletContext servletContext = req.getServletContext();
        ApplicationContext springContext=(ApplicationContext) servletContext.getAttribute("SPRING_CONTEXT_KEY");
        UserAction bean=(UserAction) springContext.getBean("userAction");
        bean.test3();
    
调用成功说明spring上下文交给了Tomcat上下文进行管理
意味着每一个servlet都能获取到spring上下文管理的所有的bean文件
<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>springXmlLocation</param-name>
            <param-value>/spring-other.xml</param-value>
        </context-param> 

</web-app>

可以变更配置文件

以上是关于spring之ioc的主要内容,如果未能解决你的问题,请参考以下文章

SpringBoot脚手架项目002-004.Spring IOC_权限管理系统_Spring:什么是IOCSpring Bean注入SpringBean的注解bean的加载流程

Springday02 jabcTemplate注解IOC创建对象注解IOC注入注解 IO生命周期纯注解IOCSpring-junitAOP-JDK和CGLIB动态代理

Spring详解(二)

JAVAWEB开发之Spring详解之——Spring的入门以及IOC容器装配Bean(xml和注解的方式)Spring整合web开发整合Junit4测试

Spring快速入门

Spring框架--Spring JDBC