• spring


    # spring介绍

    1、spring是什么?  

    一个开源的用来简化应用开发的框架。

    spring是J2EE应用程序框架,是轻量级的IoC和AOP的容器框架,主要是针对javaBean的生命周期进行管理的轻量级容器,可以单独使用,也可以和Struts框架,ibatis框架等组合使用。

    2、作用

      ##简化开发

        spring对常用的api做了封装和简化(比如,对jdbc做了封装,使用spring jdbc来访问数据库,就不用考虑获取连接和关闭连接。)

      ##简化管理

        spring提供一个容器。帮我们创建以及建立对象之间的依赖关系

        好处:降低对象之间的耦合度,方便代码的维护

      ##集成其他框架

        spring可以将其它的一些框架集成进来。(比如,集成用于任务调度的框架Quartz)。

      QQ截图20190226122512image

    1)IoC(Inversion of Control)控制反转,对象创建责任的反转,在spring中BeanFacotory是IoC容器的核心接口,负责实例化,定位,配置应用程序中的对象及建立这些对象间的依赖。XmlBeanFacotory实现BeanFactory接口,通过获取xml配置文件数据,组成应用对象及对象间的依赖关系。

    spring中有三种注入方式,一种是set注入,一种是接口注入,另一种是构造方法注入。

    2)AOP面向切面编程

       aop就是纵向的编程,业务1和业务2都需要一个共同的操作,与其往每个业务中都添加同样的代码,不如写一遍代码,让两个业务共同使用这段代码。

    spring中面向切面编程的实现有两种方式,一种是动态代理,一种是CGLIB,动态代理必须要提供接口,而CGLIB实现是有继承

    # 为什么使用spring框架

      在不使用spring框架之前,我们的service层中要使用dao层的对象,不得不在service层中new一个对象。如下:

    //dao层对象
    public class UserDao{
       publicvoid insert(User user){}
    }
     
    //service层对象
    public classUserService{
       publicvoid insert(User user){
           UserDaouserdao = new UserDao();
           userdao.insert(user);
       }
    }

    存在的问题:层与层之间的依赖。

    使用框架后:

    //dao层对象
    public class UserDao{
        public void insert(User user){}
    }
    //service层对象
    public class UserService{
       private UserDao userdao;
     
       public UserDao getUserdao() {
          returnuserdao;
       }
       public void setUserdao(UserDao userdao) {
          this.userdao= userdao;
       }
       public void insert(User user){
          userdao.insert(user);
       }
    }

    service层要用dao层对象需要配置到xml配置文件中,至于对象是怎么创建的,关系是怎么组合的都交给了spring框架去实现。

    4、框架优点

    轻量级的容器框架没有侵入性

    使用IoC容器更加容易组合对象直接间关系,面向接口编程,降低耦合

    Aop可以更加容易的进行功能扩展,遵循ocp开发原则

    创建对象默认是单例的,不需要再使用单例模式进行处理

    5、缺点:业务功能依赖spring特有的功能,依赖于spring环境

    # spring容器(IOC)

    ##什么是spring容器?

    spring框架的一个核心模块,用于管理对象。容器将创建对象,把它们连接在一起,配置它们,并管理他们的整个生命周期从创建到销毁。

    Spring 容器使用依赖注入(DI)来管理组成一个应用程序的组件。这些对象被称为 Spring Beans。IOC 容器负责实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。

    下图是 Spring 如何工作的高级视图。 Spring IoC 容器利用 Java 的 POJO 类和配置元数据来生成完全配置和可执行的系统或应用程序。

    ##Spring 提供了两种不同类型的容器。

    Spring BeanFactory 容器

    它是最简单的容器,给 DI 提供了基本的支持,它用 org.springframework.beans.factory.BeanFactory 接口来定义。BeanFactory 或者相关的接口,如 BeanFactoryAware,InitializingBean,DisposableBean,在 Spring 中仍然存在具有大量的与 Spring 整合的第三方框架的反向兼容性的目的。

    Spring ApplicationContext 容器

    该容器添加了更多的企业特定的功能,例如从一个属性文件中解析文本信息的能力,发布应用程序事件给感兴趣的事件监听器的能力。该容器是由 org.springframework.context.ApplicationContext 接口定义。

    注:ApplicationContext 容器包括 BeanFactory 容器的所有功能,所以通常建议超过 BeanFactory。

    ##启动spring容器

    step1:导包。(spring-webmvc)

    step2:添加配置文件。

    step3:启动spring容器。

    ##创建对象

    方法1:使用无参构造器

               1.给类添加无参构造器(或者缺省构造器)

               2.配置<bean>元素。

               3.调用容器的getBean方法来获得对象。

    方法2:使用静态工厂方法

               通过调用类的静态方法来创建对象。

    方法3:使用实例工厂方法

              通过调用对象的实例方法来创建对象。

    package first;
    public class Student {
        public Student() {
            System.out.println("Student()");
        }
    }
    package first;
    public class FirstSpring { public static void main(String[] args) { //1.启动spring容器 ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
    Student stu = ac.getBean("stu1",Student.class);
    System.out.println(stu);
    Date date = ac.getBean("date",Date.class);
    System.out.println(date);
    Calendar cal1 = ac.getBean("cal1",Calendar.class);
    System.out.println(cal1);
    Date time1 = ac.getBean("time1",Date.class);
    System.out.println(time1);
    }
    }
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="" xmlns:xsi=""xmlns:context="" xmlns:jdbc="" xmlns:jee="" xmlns:tx="" xmlns:aop="" xmlns:mvc="" xmlns:util="" xmlns:jpa="" xsi:schemaLocation="">
        <!-- 使用无参构造器创建对象。 id属性:bean的名称,要求唯一。 class属性:类的全限定名(即要求包名)。 -->
        <bean id="stu1" class="first.Student"></bean>
        <bean id="date" class="java.util.Date"></bean>
        <!-- 使用静态工厂方法创建对象   factory-method属性:指定一个静态方法。  spring容器会调用这个静态方法来创建对象。 -->
        <bean id="cal1" class="java.util.Calendar" factory-method="getInstance"></bean>
        <!-- 使用实例工厂方法创建对象   factory-bean属性:指定一个bean的id。  factory-method属性:指定一个方法,spring容器会调用这个bean的对应的方法来创建对象。 -->
        <bean id="time1" factory-bean="cal1" factory-method="getTime"></bean>
    </beans>

    ##作用域

    默认情况下,容器对于某个bean,只会创建一个实例。

    可以设置scope属性值为prototype,这样,容器对于某个bean会创建多个实例。

    package scope;
    public class ScopeBean {
        public ScopeBean() {
            System.out.println("ScopeBean()");
        }
    }
    <!-- scope属性:用来配置作用域,缺省值是singleton(单例), 如果值为prototype(原型)。-->
    <bean id="s1" class="scope.ScopeBean" scope="prototype"/>
    package test;public class TestCase {
        @Test//测试作用域
        public void test1() {
            ApplicationContext ac = new ClassPathXmlApplicationContext("scope.xml");//启动spring容器
         //创建对象
         ScopeBean s1 = ac.getBean("s1",ScopeBean.class);
         ScopeBean s2
    = ac.getBean("s1",ScopeBean.class);
         System.out.println(s1
    == s2);
      }
    }

    测试结果:  ScopeBean()

           false


    ##生命周期

    初始化方法:

      使用init-method属性来指定初始化方法名。

    销毁方法:

      使用destroy-method属性来指定初始化方法名。

    注:spring容器在关闭前,会销毁对象,在销毁对象之前,会先调用对象的销毁方法。

    package scope;
    public class MessageBean {
        public MessageBean() {
            System.out.println("MessageBean()");
        }
        public void init() {
            System.out.println("init()");
        }
        public void sendMsg() {
            System.out.println("sendMsg()");
        }
        public void destroy() {
            System.out.println("destroy()");
        }
    }
    <!-- init-method属性:指定初始化方法。
             destroy属性:指定销毁方法。 -->
        <bean id="mb1" class="scope.MessageBean" init-method="init" destroy-method="destroy" />
    @Test
        //测试生命周期
        public void test2() {
            //ApplicationContext 接口
            //ClassPathXmlApplicationContext 实现类
            //AbstractApplicationContext 是ApplicationContext的子接口
            AbstractApplicationContext ac = new ClassPathXmlApplicationContext("scope.xml");
            MessageBean mb1 = ac.getBean("mb1",MessageBean.class);
            mb1.sendMsg();
            ac.close();
        }

    ###延迟加载

    spring容器启动后会将所有作用域为单例的bean创建好。

    注:只有作用域为单例时,销毁方法才会执行。

    <!—lazy-init属性:指定是否延迟加载,如果为true,表示延迟加载。 -->
    <bean id="mb1" class="scope.MessageBean" init-method="init" destroy-method="destroy" 
        lazy-init="true" />

    ##IOC

    ###什么是IOC?

    对象之间的依赖关系由容器来建立。

    ###DI(依赖注入)

    容器通过调用对象提供的set方法构造器来建立依赖关系。

    IOC是目标,DI是手段。

    1.set方式注入

    package ioc;
    
    public class A {
    
        private IB ib;
        
        public void setB(IB ib) {
            System.out.println("setB()");
            this.ib = ib;
        }
    
        public A() {
            System.out.println("A()");
        }
        
        public void execute() {
            System.out.println("execute()");
            ib.f1();
        }
    
    }
    package ioc;
    public class B implements IB {
    
        public B() {
            System.out.println("B()");
        }
        
        public void f1() {
            System.out.println("B's f1()");
        }
    
    }
    
    package ioc;
    public class C implements IB {
    
        public C() {
            System.out.println("C()");
        }
        
        public void f1() {
            System.out.println("C's f1()");
        }
    
    }
    
    package ioc;
    public interface IB {
        public void f1();
    }
    <bean id="b1" class="ioc.B" />
        <bean id="c1" class="ioc.C"></bean>
        <!-- 
            property元素:表示使用set方法注入依赖关系。
            其中,name属性指定属性名,ref属性指定属性值(是被注入的bean的id)
         -->
        <bean id="a1" class="ioc.A">
            <property name="b" ref="b1"></property>
        </bean>
    @Test
        //测试set方式的注入
        public void test5() {
            ApplicationContext ac = new ClassPathXmlApplicationContext("ioc.xml");
            A a1 = ac.getBean("a1",A.class);
            a1.execute();
        }

    QQ截图20190305204805

    2.构造器方法

    package ioc2;
    public class A {
    
        private B b;
        
        public A() {
            System.out.println("A()");
        }
        
        public A(B b) {
            System.out.println("A(B)");
            this.b = b;
        }
    
        public void execute() {
            System.out.println("execute()");
            b.f1();
        }
    }
    package ioc2;
    public class B {
    
        public B() {
            System.out.println("B()");
        }
        
        public void f1() {
            System.out.println("B's f1()");
        }
    }
    <bean id="b1" class="ioc2.B" />
        <!-- 
            constructor-arg元素:用来配置构造器方式的注入,其中,
            index属性指定参数的下标(从0开始)。
         -->
        <bean id="a1" class="ioc2.A">
            <constructor-arg index="0" ref="b1"></constructor-arg>
            <!-- <constructor-arg index="1" ref="c1"></constructor-arg> -->
        </bean>
    @Test
        public void test1() {
            ApplicationContext ac = new ClassPathXmlApplicationContext("ioc2.xml");
            A a1 = ac.getBean("a1",A.class);
            a1.execute();
        }

    3.自动装配

    指的是spring容器依据某种规则,自动建立对象间的依赖关系。

    注:a.默认情况下,容器不会自动装配。

          b.可以通过指定autowire属性,来告诉容器进行自动装配

           (容器仍需要通过set方法或构造器来完成依赖关系的建立)。

    package ioc2;
    
    public class Waiter {
    
        public Waiter() {
            System.out.println("Waiter()");
        }
    }
    package ioc2;
    
    public class Restaurant {
    
        private Waiter wt;
        
        public void setWt(Waiter wt) {
            System.out.println("setWt()");
            this.wt = wt;
        }
    
        public Restaurant() {
            System.out.println("Restaurant()");
        }
    
        @Override
        public String toString() {
            return "Restaurant [wt=" + wt + "]";
        }
    }
    <!-- 
            autowire属性:自动装配,有3个属性值:
            byName:容器依据属性名查找对应的bean,然后调用对应的set方法来完成注入。
                    注:a.如果找不到对应的bean,注入null。
                        b.不可能找到多个符合条件的bean。
            byType:容器依据属性类型查找对应的bean,然后调用对应的set方法来完成注入。
                    注:a.如果找不到对应的bean,注入null。
                        b.有可能找到多个符合条件的bean,此时会出错。
            constructor:与byType类似,不同的是调用对应的构造器来完成注入。
         -->
        <bean id="wt" class="ioc2.Waiter"></bean>
        <!-- <bean id="rest" class="ioc2.Restaurant" autowire="byName" /> -->
        <bean id="rest" class="ioc2.Restaurant" autowire="byType" />
    @Test//测试自动装配
        public void test2() {
            ApplicationContext ac = new ClassPathXmlApplicationContext("ioc2.xml");
            Restaurant rest = ac.getBean("rest",Restaurant.class);
            System.out.println(rest);
        }

    ###注入基本类型的值(使用value属性即可)

    <bean id="vb1" class="value.ValueBean">
            <property name="name" value="张三"></property>
            <property name="age" value="30"></property>
        </bean>

    ###注入集合类型的值(List Set Map Properties)

    package value;
    
    import java.util.List;
    import java.util.Map;
    import java.util.Properties;
    import java.util.Set;
    
    public class ValueBean {
        private String name;
        private int age;
        private List<String> city;
        private Set<String> interest;
        private Map<String,Double> score;
        private Properties db;
        public ValueBean() {
            System.out.println("ValueBean()");
        }
        public void setScore(Map<String, Double> score) {
            this.score = score;
        }
        public void setDb(Properties db) {
            this.db = db;
        }
        public void setName(String name) {
            this.name = name;
        }
        public void setAge(int age) {
            this.age = age;
        }
        public void setCity(List<String> city) {
            this.city = city;
        }
        public void setInterest(Set<String> interest) {
            this.interest = interest;
        }
        @Override
        public String toString() {
            return "ValueBean [name=" + name + ", age=" + age + ", city=" + city + ", interest=" + interest + ", score="
                    + score + ", db=" + db + "]";
        }
    }
    <bean id="vb1" class="value.ValueBean">
            <property name="name" value="张三"></property>
            <property name="age" value="30"></property>
            <property name="city">
                <list>
                    <value>北京</value>
                    <value>南京</value>
                    <value>西京</value>
                </list>
            </property>
            <property name="interest">
                <set>
                    <value>小说</value>
                    <value>小品</value>
                </set>
            </property>
            <property name="score">
                <map>
                    <entry key="english" value="60"></entry>
                    <entry key="math" value="66"></entry>
                </map>
            </property>
            <property name="db">
                <props>
                    <prop key="username">Tiger</prop>
                    <prop key="password">1234</prop>
                </props>
            </property>
        </bean>
    @Test
        public void test3() {
            ApplicationContext ac = new ClassPathXmlApplicationContext("value.xml");
            ValueBean vb1 = ac.getBean("vb1",ValueBean.class);
            System.out.println(vb1);
        }

    输出:ValueBean()
    ValueBean [name=张三, age=30, city=[北京, 南京, 西京], interest=[小说, 小品], score={english=60.0, math=66.0}, db={password=1234, username=Tiger}]

    ###将集合类型的值配置成一个bean

    <!-- 将集合类型的值配置成一个bean -->
        <util:list id="cityBean">
            <value>上海</value>
            <value>武汉</value>
            <value>深圳</value>
        </util:list>
        <!-- 引用的方式注入集合类型的值 -->
        <bean id="vb2" class="value.ValueBean">
            <property name="city" ref="cityBean"></property>
        </bean>
    @Test
        public void test4() {
            ApplicationContext ac = new ClassPathXmlApplicationContext("value.xml");
            ValueBean vb2 = ac.getBean("vb2",ValueBean.class);
            System.out.println(vb2);
        }

    list、set、map、properties的情况和list相仿,此处不做重复。

    ###读取properties文件的内容

    <!-- 
            读取properties文件的内容
            classpath:按照类路径来搜索。
            spring容器会依据路径找到对应的properties文件,
            然后读取该文件的内容到properties对象。
         -->
        <util:properties id="config" location="classpath:config.properties"></util:properties>
    pagesize=10
    @Test
        public void test5() {
            ApplicationContext ac = new ClassPathXmlApplicationContext("value.xml");
             Object config = ac.getBean("config");
            System.out.println(config);
        }

    ###spring表达式

    可以使用spring表达式读取其它bean的属性,它的语法类似于el表达式。

    QQ截图20190306222019

  • 相关阅读:
    深度学习(dropout)
    centos 常见软件安装
    最近读的书 与论文
    如何理解反向传播 Backpropagation 梯度下降算法要点
    ubuntu 15 安装cuda,开启GPU加速
    快速排序算法
    Linux网络中接收 "二进制" 流的那些事 --- 就recv的返回值和strlen库函数进行对话
    linux源码升级编译内核
    C/C++中慎用宏(#define)
    Qt之hello world
  • 原文地址:https://www.cnblogs.com/menbozg/p/10469996.html
Copyright © 2020-2023  润新知