zoukankan      html  css  js  c++  java
  • 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的IoC

     

    IOC/DI
    将以前由程序员实例化对象/赋值的工作交给了spring处理

     

    3. 如何在spring当中定义和配置一个JavaBean(使用无参构造方法+set方法创建一个JavaBean)
    3.1 id:在容器中查找Bean的id(唯一、且不能以/开头)
    3.2 class:bean的完整类名
    3.3 name:在容器中查找Bean的名字(唯一、允许以/开头、允许多个值,多个值之间用逗号或空格隔开)
    3.4 scope:(singleton|prototype)默认是singleton
    3.4.1 singleton(单例模式):在每个Spring IoC容器中一个bean定义对应一个对象实例
    3.4.2 prototype(原型模式/多例模式):一个bean定义对应多个对象实例
    3.4 abstract:将一个bean定义成抽象bean(抽象bean是不能实例化的),抽象类一定要定义成抽象bean,非抽象类也可以定义成抽象bean
    3.5 parent:指定一个父bean(必须要有继承关系才行)
    3.6 init-method:指定bean的初始化方法
    3.7 constructor-arg:使用有参数构造方法创建javaBean

     

     我们先导入pom依赖:

         <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>4.3.10.RELEASE</version>
            </dependency>

    ioc的注入方式及各类类型
      set注入
      基本类型与string
      数组
      自定义类型

    UserAction 
    package com.huang.ioc.web;
    
    import java.util.List;
    
    import com.huang.ioc.biz.UserBiz;
    /**
     * ioc的注入方式及各类类型
     *     set注入
     *         基本类型与string
     *         数组
     *         自定义类型
     * 
     *     构造注入
     *     自动装配
     *         spring4之后出现
     *         byType:根据配置的Bean中的接口,在spring的上下文中寻找对应的实现类
     *         byName:根据配置的Bean中的接口名字,在spring的上下文寻找对应的实现类
     * 
     * @author Admin
     *
     */
    public class UserAction {
    
        private UserBiz userBiz;
        private String uname;
        private int age;
        private List<String> hobby;
    
        public UserAction(String uname, int age) {
            super();
            this.uname = uname;
            this.age = age;
        }
        public UserAction() {
            super();
        }
        public List<String> getHobby() {
            return hobby;
        }
    
        public void setHobby(List<String> hobby) {
            this.hobby = hobby;
        }
    
        public UserBiz getUserBiz() {
            return userBiz;
        }
    
        public void setUserBiz(UserBiz userBiz) {
            this.userBiz = userBiz;
        }
    
        public void upload() {
            userBiz.upload();
        }
        
        /**
         * 注入问题
         */
        public void test1() {
            System.out.println(this.uname);
            System.out.println(this.age);
            System.out.println(this.hobby);
        }
    }

    UserBiz

    package com.huang.ioc.biz;
    /**
     * 通过企业的案例来讲解使用ioc的必要性
     * v1.0:实现游戏的上传功能
     * v2.0:对游戏的上传功能进行优化
     * 
     * ioc的具体体现
     * @author Admin
     *
     */
    public interface UserBiz {
    
        public void upload();
        
    }

    再建立一个spring文件,配好对应的注入方式,然后在iocTest中调用UserAction中的方法

    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:p="http://www.springframework.org/schema/p"
        default-autowire="byType"
        xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
        xsi:schemaLocation="  
        http://www.springframework.org/schema/beans   
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
        http://www.springframework.org/schema/tx   
        http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
    
        <bean class="com.huang.ioc.biz.impl.UserBizImpl2" id="userBiz"></bean>
        <bean class="com.huang.ioc.web.UserAction" id="xxx">
            <!-- set注入用property标签 -->
             <property name="userBiz" ref="userBiz"></property> 
             <property name="uname" value="hyc"></property>
             <property name="age" value="226"></property> 
            <property name="hobby" >
                <list>
                    <value>充钱使你强大</value>
                    <value>RMB</value>
                    <value>腾讯</value>
                </list>
            </property>
        </bean>
        
        <bean class="com.huang.ioc.web.OrderAction" id="ttt">
            <!-- <property name="userBiz" ref="userBiz"></property> -->
        </bean>
        
    </beans>

    iocTest

    package com.huang.ioc.test;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import com.huang.ioc.web.OrderAction;
    import com.huang.ioc.web.UserAction;
    
    public class IocTest {
        public static void main(String[] args) {
           
            ApplicationContext springContext= new ClassPathXmlApplicationContext("/spring-context.xml"); 
            UserAction userAction=(UserAction) springContext.getBean("xxx");
            userAction.test1();
        }
    }

    运行效果:

    构造注入

    把property换成constructor-arg即可,效果一致
    <?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:p="http://www.springframework.org/schema/p"
        default-autowire="byType"
        xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
        xsi:schemaLocation="  
        http://www.springframework.org/schema/beans   
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
        http://www.springframework.org/schema/tx   
        http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
    
        <bean class="com.huang.ioc.biz.impl.UserBizImpl2" id="userBiz"></bean>
        <bean class="com.huang.ioc.web.UserAction" id="xxx">
            <!-- 构造注入用constructor-arg标签 -->
            <constructor-arg name="uname" value="ls"></constructor-arg>
            <constructor-arg name="age" value="22"></constructor-arg>
            <property name="hobby" >
                <list>
                    <value>充钱使你强大</value>
                    <value>RMB</value>
                    <value>腾讯</value>
                </list>
            </property>
        </bean>
        
        <bean class="com.huang.ioc.web.OrderAction" id="ttt">
            <!-- <property name="userBiz" ref="userBiz"></property> -->
        </bean>
        
    </beans>

    自动装配:

    byType:根据配置的Bean中的接口,在spring的上下文中寻找对应的实现类

    byName:根据配置的Bean中的接口名字,在spring的上下文寻找对应的实现类

    UserBizImpl1

    package com.huang.ioc.biz.impl;
    
    import com.huang.ioc.biz.UserBiz;
    
    public class UserBizImpl1 implements UserBiz{
    
        @Override
        public void upload() {
            System.out.println("实现用户上传的功能");
        }
    
    }

    UserBizImpl2

    package com.huang.ioc.biz.impl;
    
    import com.huang.ioc.biz.UserBiz;
    
    public class UserBizImpl2 implements UserBiz{
    
        @Override
        public void upload() {
            System.out.println("开始优化性能的代码");
            System.out.println("实现用户上传的功能");
            
        }
     
        
    }

    iocTest

    package com.huang.ioc.test;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import com.huang.ioc.web.OrderAction;
    import com.huang.ioc.web.UserAction;
    
    public class IocTest {
        public static void main(String[] args) {
            
    //        UserAction userAction=new UserAction();
    //        userAction.upload(); 
            
            ApplicationContext springContext= new ClassPathXmlApplicationContext("/spring-context.xml"); 
            UserAction userAction=(UserAction) springContext.getBean("xxx");
            OrderAction orderAction=(OrderAction) springContext.getBean("ttt");
            userAction.upload();
            orderAction.upload();
    //        userAction.test1();
        }
    }

    spring 作为管理整个工程中的所有的javabean.那么如何在用户发送请求的时候能够访问到指定的javabean呢?
     处理方式
     在监听器中将spring的上下文交给tomcat的上下文进行管理
     浏览器-->request-->servletContext-->springContext-->任意的javaBean

    springloaderListener

    package com.huang.ioc.listener;
    
    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;
    
    @WebListener
    public class SpringLoaderListener implements ServletContextListener {
    
    
        @Override
        public void contextInitialized(ServletContextEvent sce) {
            System.out.println("tomcat一启动就触发了......");
            ServletContext tomcatContext = sce.getServletContext();
            String springXmlLocation = tomcatContext.getInitParameter("springXmlLocation");
            System.out.println("spring的上下文配置文件:"+springXmlLocation);
            ApplicationContext springContext = null;
            if(springXmlLocation == null || "".equals(springXmlLocation)) {
                springContext = new ClassPathXmlApplicationContext("/spring-context.xml"); 
            }
            else {
                springContext = new ClassPathXmlApplicationContext(springXmlLocation); 
            }
            tomcatContext.setAttribute("spring_key", springContext);
        }
    
        
    
        
    }

    UserServlet

    package com.huang.ioc.web;
    
    import java.io.IOException;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebListener;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.springframework.context.ApplicationContext;
    
    @WebListener("/user")
    public class UserServlet extends HttpServlet {
     
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
        }
        
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("处理用户请求");
        ApplicationContext springContext = (ApplicationContext) req.getServletContext().getAttribute("spring_key");
        UserAction userAction = (UserAction) springContext.getBean("xxx");
        userAction.upload();
        }
    }

    然后再web.xml中配置:

    <context-param>
            <param-name>springXmlLocation</param-name>
            <param-value>/spring-other.xml</param-value>
        </context-param>

  • 相关阅读:
    记录python爬取猫眼票房排行榜(带stonefont字体网页),保存到text文件,csv文件和MongoDB数据库中
    分析Ajax来爬取今日头条街拍美图并保存到MongDB
    把SQLAlchemy查询对象转换成字典/json使用(汇总)
    把SQLAlchemy查询对象转换成字典/json使用(分开)
    使用Flask_SQLAlchemy连接多个数据库
    SQLAlchemy小知识点
    flask_sqlalchemy和sqlalchemy联系区别及其使用方式
    使用Requests+正则表达式爬取猫眼TOP100电影并保存到文件或MongoDB,并下载图片
    使用python脚本定时备份web网站
    使用shell脚本定时备份web网站代码
  • 原文地址:https://www.cnblogs.com/bf6rc9qu/p/11336838.html
Copyright © 2011-2022 走看看