Spring

Spring范围很广,暂且开一篇胡乱拼,后期增多了内容再细分。

Spring(一),Spring(

1.1 Spring框架的概述

 

1.1.1什么是Spring

  • Spring是分层的JavaSE和JavaEES一站式轻量级开源框架。
    • 分层:
      • SUN提供的EE的三层结构:web层、业务层、数据访问层(持久层、集成层)。
      • Struts2是web层基于MVC设计模式框架。
      • Hibernate是持久层的一个ORM框架。
    • 一站式:
      • Spring框架有对三层的每层解决方案:
      • web层:Spring MVC。
      • 持久层:JDBC Template。
      • 业务层:Spring的Bean管理。

 

1.1.2Spring的核心

  • IOC(Inverse of control):控制反转。
    • 控制反转:将对象的创建权,交由Spring管理。
    • IOC原理:

图片 1

  • AOP(Aspect Oriented Programming):面向切面编程。
    • 面向切面编程:是面向对象的功能延伸,不是替换面向对象,是用来解决面向对象的一些问题。 

 

1.1.3Spring的版本

  • Spring3.x版本和Spring4.x版本。Spring4.x版本需要整合Hibernate4.x版本。

 

1.1.4EJB:企业级的JavaBean

  • EJB:SUN公司提出的EE解决方案。

 

1.1.5Spring的优点

  • 方便解耦,简化开发
    • Spring就是一个大工厂,可以将所有对象创建和依赖关系维护,交由Spring管理。
  • AOP编程的支持
    • Spring提供面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等功能。
  • 声明式事务的支持
    • 只需要通过配置就可以完成对事务的管理,无需手动编程。
  • 方便程序的测试
    • Spring对Junit4支持,可以通过注解方便的测试Spring程序。  
  • 方便集成各种优秀框架
    • Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如:Struts2、Hibernate、MyBatis、Quartz等)的直接支持。  
  • 降低JavaEE API的使用难度
    • Spring对JavaEE开发中非常难用的一些API(JDBC、JavaMail、远程调用等),都提供了封装,使得这些API应用难度大大降低。

 

1.2 Spring的入门        

1.2.1Spring的体系结构

  • Spring框架是一个分层架构,它包含了一系列的功能要素并被分为大约20个模块。这些模块分为Core
    Container、Data Access/Integration、Web、AOP(Aspect Oriented
    Programming)、Instrumentation和测试部分。

图片 2

 

1.2.2下载Spring的开发包

  • spring-framework-3.2.0.RELEASE-dist.zip     –Spring开发包
    • docs:Spring框架的API和规范。
    • libs:Spring开发的jar包。
    • schema:XML的约束文档。  
  • spring-framework-3.0.2.RELEASE-dependencies.zip
     –Spring开发中的依赖包

 

1.2.3创建web工程并引入相应的jar包。

  • Core Container:
    • spring-beans-3.2.0.RELEASE.jar
    • spring-core-3.2.0.RELEASE.jar
    • spring-context-3.2.0.RELEASE.jar
    • spring-expression-3.2.0.RELEASE.jar
  • 开发的日志记录的jar包:
    • com.springsource.org.apache.commons.logging-1.1.1.jar
       用于整合其他的日志的jar包(类似于Hibernate中的slf4j)
    • com.springsource.org.apache.log4j-1.2.15.jar  

 

1.2.4创建Spring的配置文件

  • 在src下新建一个applicationContext.xml文件
  • 引入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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> 


 </beans>

 

1.2.5引入log4j.properties

### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.err
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### direct messages to file mylog.log ###
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=c\:mylog.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### set log levels - for more verbose logging change 'info' to 'debug' ###

log4j.rootLogger=info, stdout

 

 1.2.6体验传统开发和Spring开发

  • 创建一个接口:HelloService.java。

package cn.spring3.demo1;
/**
 * 入门的案例
 */
public interface HelloService {
    public void sayHello();
}
  • 创建一个实现类:HelloServiceImpl.java。

package cn.spring3.demo1;

public class HelloServiceImpl implements HelloService {

    @Override
    public void sayHello() {
        System.out.println("Hello Spring");

    }



}
  • 传统方式开发–多态

  @Test
    //传统方式
    public void demo1(){
        HelloService helloService = new HelloServiceImpl();
        helloService.sayHello();
    }
  • Spring开发
    • 要在applicationContext.xml文件中配置<bean>标签
      • <!–
        通过<bean>标签设置类的信息,通过id属性为类起个标识
        –>
        <bean id=”helloServiceImpl”
        class=”cn.spring3.demo1.HelloServiceImpl”/>

    • applicationContext.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> 

     <!-- 
         通过<bean>标签设置类的信息,通过id属性为类起个标识
      -->
     <bean id="helloServiceImpl" class="cn.spring3.demo1.HelloServiceImpl"/>
 </beans>      
    • 测试代码

  @Test
    //Spring开发
    public void demo2(){
        //创建一个工厂类
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        HelloService helloService = (HelloService) applicationContext.getBean("helloServiceImpl");
        helloService.sayHello();
    }

 

1.2.7IOC和DI的区别?

  • IOC:控制反转,将对象的创建权,交由Spring管理。
  • DI:依赖注入,在Spring创建对象的过程之中,把对象的属性注入到类中。
    • 面向对象中对象之间的关系
      • 依赖:

public class A{
      private B b;              
}
      • 继承:is a。
      • 聚合:
        • 聚集
        • 组合
    • 示例:

      • HelloService.java类

package cn.spring3.demo1;
/**
 * 入门的案例
 */
public interface HelloService {
    public void sayHello();
}
      • HelloServiceImpl.java类    

package cn.spring3.demo1;

public class HelloServiceImpl implements HelloService {
    private String info;


    public String getInfo() {
        return info;
    }


    public void setInfo(String info) {
        this.info = info;
    }


    @Override
    public void sayHello() {
        System.out.println("Hello"+info);

    }



}
      • applicationContext.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> 

     <!-- 
         通过<bean>标签设置类的信息,通过id属性为类起个标识
      -->
     <bean id="helloServiceImpl" class="cn.spring3.demo1.HelloServiceImpl">
         <!-- 使用 <property>标签注入属性-->
         <property name="info" value="Spring"></property>
     </bean>
 </beans>      
      • 测试代码

  @Test
    //Spring开发
    public void demo2(){
        //创建一个工厂类
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        HelloService helloService = (HelloService) applicationContext.getBean("helloServiceImpl");
        helloService.sayHello();

    }

 

1.2.8Spring框架加载配置文件

  • ApplicationContext(应用上下文),加载Spring框架配置文件。
    • 加载classpath:
      • new
        ClassPathXmlApplicationContext(“applicationContext.xml”);    
               :加载classpath下面配置文件。
    • 加载磁盘路径:
      • new
        FileSystemXmlApplicationContext(“applicationContext.xml”);  
            :加载磁盘下配置文件。

 

 

1.2.9BeanFactory和ApplicationContext区别?

图片 3

 

  • ApplicationContext类继承了BeanFactory。
  • BeanFactory在使用到这个类的时候,getBean()方法才会加载到这个类。(延迟加载)。
  • ApplicationContext类加载配置文件的时候,创建所有的类。
  • ApplicationContext对BeanFactory提供了扩展的功能。
    • 国际化处理。
    • 事件传递。
    • Bean自动装配。
    • 各种不同应用层的Context实现。
  • ****早期开发使用BeanFactory。

 

1.2.10MyEclipse配置XML提示

  • 复制Schema的Location。

图片 4

  • windows–preferences–XML Catalog

图片 5

图片 6

图片 7

                  

1.3 IOC装配Bean    

1.3.1Spring框架Bean实例的方式:

  • 提供了三种方式实例化Bean。
    • 构造方法实例化:(默认无参数)–反射
      • <bean id=”helloServiceImpl”
        class=”cn.spring3.demo1.HelloServiceImpl”/>

package cn.spring3.demo2;
/**
 * 使用无参数的方法实例化
 */
public class Bean1 {

}

<bean id="bean1" class="cn.spring3.demo2.Bean1"></bean>

  @Test
    //无参数的构造方法实例化
    public void demo1(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        Bean1 bean1= (Bean1) applicationContext.getBean("bean1");
        System.out.println(bean1);
    }
    • 静态工厂方法实例化(简单工厂模式)–反射+简单工厂

package cn.spring3.demo2;
/**
 * 使用静态工厂实例化
 */
public class Bean2 {

}

package cn.spring3.demo2;
/**
 * Bean2的静态工厂
 */
public class Bean2Factory {
    public static Bean2 getBean2Instance(){
        return new Bean2();
    }
}

<bean id="bean2Factory" class="cn.spring3.demo2.Bean2Factory" factory-method="getBean2Instance" ></bean>

  @Test
    //使用静态工厂实例化
    public void demo2(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        Bean2 bean2= (Bean2) applicationContext.getBean("bean2Factory");
        System.out.println(bean2);
    }
    • 实例工厂实例化(工厂方法模式) —反射+实例工厂 

package cn.spring3.demo2;
/**
 * 使用实例工厂
 */
public class Bean3Factory {
    public Bean3 getBean3Instance(){
        return new Bean3();
    }
}

package cn.spring3.demo2;
/**
 * 使用实例工厂实例化
 */
public class Bean3 {

}

   <!-- 用来初始化Bean3Factory -->
     <bean id="bean3Factory" class="cn.spring3.demo2.Bean3Factory"></bean>
     <bean id="bean3" factory-bean="bean3Factory" factory-method="getBean3Instance" ></bean>

  @Test
    //使用实例工厂实例化
    public void demo3(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        Bean3 bean3= (Bean3) applicationContext.getBean("bean3");
        System.out.println(bean3);
    }
  • 分析:
    • 构造方法实例化:(默认无参数)–反射
      • 直接给Spring一个完整的类名,Spring就会帮助我们实例化对象。
    • 静态工厂方法实例化(简单工厂模式)
      • 要给一个factory-method,因为静态方法可以直接通过类名.方法()的形式来调用方法,而class=””,当然是静态工厂的类名了,因为只有这样Spring才能帮助我们初始化工厂,返回需要的实例化对象。
    • 实例工厂实例化(工厂方法模式)
      • 之所以要实例化工厂,因为实例工厂不是静态工厂,不可以通过类名.方法()的形式调用方法,所以必须先让Spring来实例化实例工厂,然后再告诉Spring实例工厂的对象名是什么以及什么方法来实例化对象的。

 

1.3.2Bean的其他配置 

  • id和name的区别           
    • id遵守XML约束的id的约束。id约束保证这个属性的值是唯一的,而且必须以字母开始,可以使用字母、数字、连字符、下划线、句号、冒号。
    • name没有这些要求
      • 如果bean标签上没有配置id,那么name可以作为id。
    • 早期开发的时候,Spring整合Struts1,”/login”是特殊字符,只能使用name。
      • <bean name=”/login”/>
    • 现在的开发中都使用id属性即可。  

 

 

  • 类的作用范围: 
    • scope属性:
      • singleton:单例的。(默认值)
      • prototype:多例的。
      • request:web开发中使用。创建一个对象,将这个对象存入request范围,request.setAttribute()。
      • session:web开发中使用。创建一个对象,将这个对象存入session范围,session.setAttribute()。
      • globalSession:一般用于Porlet应用环境,指的是分布式开发。不是Porlet环境,globalSession等同于session。
    • 实际开发中主要使用的是singleton和prototype。  

 

  • Bean的生命周期
    • 配置Bean的初始化的销毁的方法
      • init-method=”setUp”。
      • destory-method=”teardown” 。
    • 执行销毁的时候,必须手动关系工厂,而且支队scope=”singleton”有效。 

 

    • 示例:
      • Product.java

package cn.spring3.demo3;

public class Product {

    //初始化的方法
    public void setup(){
        System.out.println("初始化的方法");
    }
    //销毁的方法
    public void teardown(){
        System.out.println("销毁的方法");
    }
}
      • applicationContext.xml

<bean id="product" class="cn.spring3.demo3.Product" init-method="setup" destroy-method="teardown"/>
      • 测试代码:

  @Test
    //测试初始化和销毁的方法
    public void demo1(){
        ClassPathXmlApplicationContext applicationContext  = new ClassPathXmlApplicationContext("applicationContext.xml");
        Product product = (Product) applicationContext.getBean("product");
        applicationContext.close();
    }
    • Bean的生命周期的11个步骤:

 

 

 

 

 

 

 

 

 

    

    

    

       

 

 

 

 

 

           

1.1 Spring框架的概述
1.1.1什么是Spring Spring是分层的JavaSE和JavaEES一站式轻量级开源框架。
分层: SUN提供的EE的三层结构:…

Spring生态系统

Spring(一),Spring(

一、 spring是什么?

我们知道struts 是 web 框架 (jsp/action/actionfrom)。hibernate 是
orm框架,处于持久层。

spring 是容器框架,用于配置bean,并维护bean之间关系的框架。

spring中非常重要的概念:

bean (是java中的任何一种对象 javabean/service/action/数据源./dao

ioc(控制反转 inverse of control)

di( dependency injection 依赖注入)

图片 8

 

二、 快速入门

开发一个spring项目.

1.引入spring的开发包(最小配置spring.jar 该包把常用的jar都包括, 还要
写日志包 common-logging.jar

2.创建spring的一个核心文件(容器文件) applicationContext.xml,
[hibernate有核心 hibernate.cfg.xml struts核心文件 struts-config.xml],
该文件一般放在src目录下,该文件中引入 xsd文件
:可以从给出的案例中拷贝一份.

3.配置bean

<!– 在容器文件中配置bean(service/dao/domain/action/数据源) –>

<!–
bean元素的作用是,当我们的spring框架加载时候,spring就会自动的创建一个bean对象,并放入内存

UserService userSerivce=new UserService();

userSerivce.setName(“韩顺平”);

–>

<bean id=”userService” class=”com.service.UserService”>

<!– 这里就体现出注入的概念. –>

<property name=”name”>

       <value>韩顺平</value>

</property>

</bean>

4.在Test.java中,我们怎么使用

//我们现在使用spring来完成上面的任务

              //1.得到spring 的applicationContext对象(容器对象)

              ApplicationContext  ac=new
ClassPathXmlApplicationContext(“applicationContext.xml”);

              UserService us=(UserService) ac.getBean(“userService”);

              us.sayHello();

讨论:

传统的方法和使用spring的方法

1.使用spring ,没有new 对象,我们把创建对象的任务交给spring框架

2.spring的运行原理图:

图片 9

总结:

spring实际上是一个容器框架,可以配置各种bean(action/service/domain/dao),并且可以维护bean与bean的关系,当我们需要使用某个bean的时候,我们可以getBean(id),使用即可.

ioc是什么?

答 :ioc(inverse of controll ) 控制反转:
所谓控制反转就是把创建对象(bean),和维护对象(bean)的关系的权利从程序中转移到spring的容器(applicationContext.xml),而程序本身不再维护.

DI是什么?

答: di(dependency injection) 依赖注入:
实际上di和ioc是同一个概念,spring设计者认为di更准确表示spring核心技术

注意:Applicationcontext是一个重量级对象,所以要把Applicationcontext做成一个单例的。

 

三、spring与接口编程

 spring开发提倡接口编程,配合di技术可以层与层的解耦

举例说明:

现在我们体验一下spring的di配合接口编程的,完成一个字母大小写转换的案例思路:

在业务层中使用接口调用方式,改变Spring容器中的配置切换不同的接口实现方式即可改变业务逻辑而不需要改变业务层的代码。

通过上面的案例,我们可以初步体会到di配合接口编程,的确可以减少层(web层)
和 业务层的耦合度.

 

四、从ApplicationContext
应用上下文容器中获取bean和从bean工厂容器中获取bean

图片 10

具体案例:

//从ApplicationContext中取bean

ApplicationContext ac=new
ClassPathXmlApplicationContext(“com/hsp/ioc/beans.xml”);

//当我们去实例化beans.xml,该文件中配置的bean被实例(该bean scope是
singleton)从bean中取出student        

       

//如果我们使用beanfactory去获取bean,当你只是实例化该容器, 那么

     
//容器的bean不被实例化,只有当你去使用getBean某个bean时,才会实时的创建. 
     

              BeanFactory factory = new XmlBeanFactory(new
ClassPathResource(“com/hsp/ioc/beans.xml”));

              factory.getBean(“student”);

结论:

1.如果使用ApplicationContext ,则配置的bean如果是 singleton
(非singleton则不会)不管你用不用,都被实例化.(好处就是可以预先加载,缺点就是耗内存)

2.如果是 BeanFactory
,则当你获取beanfacotry时候,配置的bean不会被马上实例化,当你使用的时候,才被实例(好处节约内存,缺点就是速度)

3.规定: 一般没有特殊要求,应当使用ApplicatioContext完成

 

三种获取ApplicationContext 对象引用的方法

1.ClassPathXmlApplicationContext -> 通过类路径

2.FileSystemXmlApplicationContext -> 通过文件路径

举例:

ApplicationContext ac=new
FileSystemXmlApplicationContext(“文件路径beans.xml /
applicationContext.xml”);

D:\\myspringsrc\\com\\hsp\\ioc\\beans.xml 要用绝对路径

3.XmlWebApplicationContext  当tomcat启动的时候加载

 

五、bean的生命周期

为什么总是一个生命周期当做一个重点?

Servlet -> servlet生命周期 init() destory()

图片 11


 实例化(当我们的程序加载beans.xml文件),把我们的bean(前提是scope=singleton)实例化到内存(spring
容器)

②  调用set方法设置属性

③  如果你实现了bean名字关注接口(BeanNameAware)
则,可以通过setBeanName获取id号(bean的名字)

④  如果你实现了
bean工厂关注接口,(BeanFactoryAware),则可以获取BeanFactory

如果是单例模式bean工厂在每个bean创建的时候都创建一次。

如果是prototype模式bean工厂则只会创建一次。

⑤  如果你实现了 ApplicationContextAware接口,则调用方法

 如果bean 和 一个后置处理器关联,则会自动去调用 Object
postProcessBeforeInitialization方法

⑦  如果你实现InitializingBean 接口,则会调用 afterPropertiesSet

⑧  如果自己在<bean init-method=”init” />
则可以在bean定义自己的初始化方法.

 如果bean 和 一个后置处理器关联,则会自动去调用 Object
postProcessAfterInitialization方法

⑩ 使用我们的bean

其中非常有价值的是⑥⑨
面向切面编程。相当于一个filter过滤器。配置关联之后将对所有的bean有效。

 图片 12

  1. 容器关闭

  2. 可以通过实现DisposableBean 接口来调用方法 destory

  3. 可以在<bean destory-method=”fun1”/> 调用定制的销毁方法

 

小结: 我们实际开发中往往,没有用的这么的过程,常见的是:

1->2->6->9->10->11 

 

问题:通过BeanFactory来获取bean对象,bean的生命周期是否和Applicationcontext
是一样吗?

 

不是一样的,bean是工厂中创建的生命周期会简单一些:

 

 图片 13

 

 

 

一、 spring是什么?
我们知道struts 是 web 框架 (jsp/action/actionfrom)。hibernate 是
orm框架,处于持久层。 spring 是 容器框架 ,用于…

序言

Spring
Cloud是Spring家族中的微服务应用开发组件。它为基于JVM的微服务应用开发中的配置管理、服务发现、断路器、智能路由、微代理、控制总线、全局锁、决策竞选、分布式会话和集群状态管理等操作提供了一种简单的开发方式。

微服务架构,就是是将应用拆散。将原来集中在一个庞大应用中的各个功能分离出来,形成一个个独立开发,独立部署,独立运维的微型服务应用。服务之间通过网络通信协议和约定的接口进行协作,实现完整的业务功能。

Spring Cloud基于Spring Boot实现,Spring
Boot又以Spring框架为基础。因此,要开发Spring Cloud应用,就必须要对Spring
Boot和Spring框架有所了解。这篇文章作为系列中的第一篇,目标是为大家打下基础中的第一根桩,让大家能快速上手,同时为大家的深入学习指明第一个方向。

1 渊源

学习重点

Spring框架

Spring框架的核心是控制反转(Inverse of Control,
IoC)和面向切面编程(Aspect-Oriented Programming, AOP)

1.1 spring

1、Spring是什么

简单来说,Spring就是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。从简单性、可测试性和松耦合的角度而言,任何Java应用都可以从Spring中受益。

下面是Spring的一些特性;所有Spring的这些特征都能帮助我们够编写更干净、更可管理、并且更易于测试的代码。它们也为Spring中的各种模块提供了基础支持。

原型在200210由Rod Johnson发布的书中体现,后来在200403spring
1.0版本发布,201709spring 5.0发布,

轻量

从大小与开销两方面而言Spring都是轻量的。此外,Spring是非侵入式的:使用Spring,我们的类还是pojo类,完全不用继承和实现Spring的类和接口等。也就是说,使用Spring的应用中的对象不依赖于Spring的特定类。

spring ioc

IoC

Spring通过控制反转技术促进了松耦合。当应用了IoC,一个对象依赖的其它对象会通过被动的方式传递进来,而不是这个对象自己创建或者查找依赖对象。可以认为IoC与JNDI相反——不是我们自己控制对象从容器中查找依赖,而是容器在对象初始化时不等对象请求就主动将依赖传递给它,这就是DI——依赖注入

IOC和DI是从两个角度描述同一个事物:

反转控制——哪些方面的控制被反转了呢?答案是获得依赖对象的过程被反转了。控制被反转之后,获得依赖对象的过程由自身管理变为了由IOC容器主动注入,于是“反转控制”有了一个新的名字,叫做“依赖注入”。

依赖注入——所谓依赖注入,就是由IOC容器在运行期间,动态地将某种依赖关系注入到对象之中。

控制反转,管理容器中的bean,主要使用di依赖注入实现。

AOP

Spring提供了面向切面的编程支持,AOP将与程序业务无关的内容分离提取,应用对象只实现它们应该做的——完成业务逻辑——仅此而已。它们并不负责其它的系统级关注点,例如日志或事务支持。AOP将与业务无关的逻辑横切进真正的逻辑中。

springAop

框架

Spring可以将简单的组件配置、组合成为复杂的应用。在Spring中,应用对象被声明式地组合,典型地是在一个XML文件里。Spring也提供了很多基础功能(事务管理、持久化框架集成等等),而用户就有更多的时间和精力去开发应用逻辑。

面向切面,调用者和被调用者解藕,用于权限、缓存等功能实现。

Spring的优点——为什么要用Spring
  • 借助Spring,通过依赖注入、AOP应用、面向接口编程,来降低业务组件之间的耦合度,增强系统的扩展性。
  • 让已有的技术和框架更加易用。
  • 利用其对hibernate的SessionFactory、事务管理的封装,更简洁的应用hibernate。
  • Spring并不完全依赖于Spring,开发者可自由选用Spring框架的部分或全部
  • 利用AOP思想,集中处理业务逻辑,减少重复代码,构建优雅的解决方案。
  • 低侵入式设计,代码污染极低。

spring transaction

2、使用IOC容器为什么能够解耦?

参考:Spring
IOC为什么可以实现解耦

事务管理,一通过配置文件,二基于注解

对象之间的过高耦合问题

在采用面向对象方法设计的软件系统中,它的底层实现都是由N个对象组成的,所有的对象通过彼此的合作,最终实现系统的业务逻辑。:

对象解耦与齿轮咬合的情形类似

齿轮组中齿轮之间的啮合关系,与软件系统中对象之间的耦合关系非常相似。对象之间的耦合关系是无法避免的,也是必要的,这是协同工作的基础。现在,伴随着工业级应用的规模越来越庞大,对象之间的依赖关系也越来越复杂,经常会出现对象之间的多重依赖性关系,因此,架构师和设计师对于系统的分析和设计,将面临更大的挑战。对象之间耦合度过高的系统,必然会出现牵一发而动全身的情形。

对象之间解耦严重

耦合关系不仅会出现在对象与对象之间,也会出现在软件系统的各模块之间,以及软件系统和硬件系统之间。如何降低系统之间、模块之间和对象之间的耦合度,是软件工程永远追求的目标之一。为了解决对象之间的耦合度过高的问题,软件专家Michael
Mattson提出了IOC理论,用来实现对象之间的“解耦”,目前这个理论已经被成功地应用到实践当中,很多的J2EE项目均采用了IOC框架产品Spring。

springmvc

IOC解耦过程

IOC把复杂系统分解成相互合作的对象,这些对象类通过封装以后,内部实现对外部是透明的,从而降低了解决问题的复杂度,而且可以灵活地被重用和扩展。IOC理论提出的观点大体是这样的:借助于“第三方”实现具有依赖关系的对象之间的解耦

“第三方”——IOC容器

由于引进了中间位置的“第三方”,也就是IOC容器,使得A、B、C、D这4个对象没有了耦合关系,齿轮之间的传动全部依靠“第三方”了,全部对象的控制权全部上缴给“第三方”IOC容器,所以,IOC容器成了整个系统的关键核心,它起到了一种类似“粘合剂”的作用,把系统中的所有对象粘合在一起发挥作用,如果没有这个“粘合剂”,对象与对象之间会彼此失去联系,这就是有人把IOC容器比喻成“粘合剂”的由来。

我们再来做个试验:把上图中间的IOC容器拿掉,然后再来看看这套系统:

拿掉IoC容器后的系统

我们现在看到的画面,就是我们要实现整个系统所需要完成的全部内容。这时候,A、B、C、D这4个对象之间已经没有了耦合关系,彼此毫无联系,这样的话,当你在实现A的时候,根本无须再去考虑B、C和D了,对象之间的依赖关系已经降低到了最低程度。所以,如果真能实现IOC容器,对于系统开发而言,这将是一件多么美好的事情,参与开发的每一成员只要实现自己的类就可以了,跟别人没有任何关系

数据,业务,展示分离

为什么叫“控制反转”

软件系统在没有引入IOC容器之前,对象A依赖于对象B,那么对象A在初始化或者运行到某一点的时候,自己必须主动去创建对象B或者使用已经创建的对象B。无论是创建还是使用对象B,控制权都在自己手上。
软件系统在引入IOC容器之后,这种情形就完全改变了,由于IOC容器的加入,对象A与对象B之间失去了直接联系,所以,当对象A运行到需要对象B的时候,IOC容器会主动创建一个对象B注入到对象A需要的地方

spring security

IOC的别名:依赖注入(DI)

2004年,Martin
Fowler探讨了同一个问题,既然IOC是控制反转,那么到底是“哪些方面的控制被反转了呢?”,经过详细地分析和论证后,他得出了答案:“获得依赖对象的过程被反转了”。控制被反转之后,获得依赖对象的过程由自身管理变为了由IOC容器主动注入。于是,他给“控制反转”取了一个更合适的名字叫做“依赖注入(Dependency
Injection)”。他的这个答案,实际上给出了实现IOC的方法:注入。所谓依赖注入,就是由IOC容器在运行期间,动态地将某种依赖关系注入到对象之中。

所以,依赖注入(DI)和控制反转(IOC)是从不同的角度的描述的同一件事情,就是指通过引入IOC容器,利用依赖关系注入的方式,实现对象之间的解耦。

提供声明式的安全访问控制解决方案的安全框架。它提供了一组可以spring应用上下文中配置的bean,为应用提供声明式的安全访问控制功能。

IOC容器的技术剖析

IOC中最基本的技术就是“反射(Reflection)”编程,目前.Net
C#、Java和PHP5等语言均支持,其中PHP5的技术书籍中,有时候也被翻译成“映射”。有关反射的概念和用法,大家应该都很清楚,通俗来讲就是根据给出的类名(字符串方式)来动态地生成对象。这种编程方式可以让对象在生成时才决定到底是哪一种对象。反射的应用是很广泛的,很多的成熟的框架,比如象Java中的Hibernate、Spring框架,.Net中
NHibernate、Spring.Net框架都是把“反射”做为最基本的技术手段。

反射技术其实很早就出现了,但一直被忽略,没有被进一步的利用。当时的反射编程方式相对于正常的对象生成方式要慢至少得10倍。现在的反射技术经过改良优化,已经非常成熟,反射方式生成对象和通常对象生成方式,速度已经相差不大了,大约为1-2倍的差距。

我们可以把IOC容器的工作模式看做是工厂模式的升华,可以把IOC容器看作是一个工厂,这个工厂里要生产的对象都在配置文件中给出定义,然后利用编程语言的的反射编程,根据配置文件中给出的类名生成相应的对象。从实现来看,IOC是把以前在工厂方法里写死的对象生成代码,改变为由配置文件来定义,也就是把工厂和对象生成这两者独立分隔开来,目的就是提高灵活性和可维护性。

spring schedule

3、理解AOP

参考:Spring AOP
实现原理

基于spring能用统一的配置和编码风格来使用schedule方案,支持Jdk
time、concurrent、quartz

为什么会有AOP

AOP(Aspect-OrientedProgramming,面向方面编程),可以说是OOP(Object-Oriented
Programing,面向对象编程)的补充和完善。OOP引入封装、继承和多态性等概念来建立一种对象层次结构,用以模拟公共行为的一个集合。当我们需要为分散的对象引入公共行为的时候,OOP则显得无能为力。也就是说,OOP允许你定义从上到下的关系,但并不适合定义从左到右的关系。例如日志功能。日志代码往往水平地散布在所有对象层次中,而与它所散布到的对象的核心功能毫无关系。对于其他类型的代码,如安全性、异常处理和透明的持续性也是如此。这种散布在各处的无关的代码被称为横切(cross-cutting)代码在OOP设计中,它导致了大量代码的重复,而不利于各个模块的重用

而AOP技术则恰恰相反,它利用一种称为“横切”的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其名为“Aspect”,即方面。所谓“方面”,简单地说,就是将那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可操作性和可维护性。AOP代表的是一个横向的关系,如果说“对象”是一个空心的圆柱体,其中封装的是对象的属性和行为;那么面向方面编程的方法,就仿佛一把利刃,将这些空心圆柱体剖开,以获得其内部的消息。而剖开的切面,也就是所谓的“方面”了。然后它又以巧夺天功的妙手将这些剖开的切面复原,不留痕迹。

使用“横切”技术,AOP把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点。横切关注点的一个特点是,他们经常发生在核心关注点的多处,而各处都基本相似。比如权限认证、日志、事务处理。Aop
的作用在于分离系统中的各种关注点,将核心关注点和横切关注点分离开来。正如Avanade公司的高级方案构架师Adam
Magee所说,AOP的核心思想就是“将应用程序中的商业逻辑同对其提供支持的通用服务进行分离。”

1.2 spring boot

实现AOP的技术

主要分为两大类:一是采用动态代理技术,利用截取消息的方式,对该消息进行装饰,以取代原有对象行为的执行;二是采用静态织入的方式,引入特定的语法创建“方面”,从而使得编译器可以在编译期间织入有关“方面”的代码。

由于spring的边界不断的进行扩充,导致了基础配置越来越复杂,spring
boot应运而生,201404springboot 1.0.0发布,其核心思想,约定大于配置。

AOP使用场景

AOP用来封装横切关注点,具体可以在下面的场景中使用:

  • Authentication 权限
  • Caching 缓存
  • Context passing 内容传递
  • Error handling 错误处理
  • Lazy loading 懒加载
  • Debugging 调试
  • logging, tracing, profiling and monitoring 记录跟踪 优化 校准
  • Performance optimization 性能优化
  • Persistence 持久化
  • Resource pooling 资源池
  • Synchronization 同步
  • Transactions 事务

引入web模块

AOP相关概念

方面(Aspect):一个关注点的模块化,这个关注点实现可能另外横切多个对象。事务管理是J2EE应用中一个很好的横切关注点例子。方面用spring的
Advisor或拦截器实现。

连接点(Joinpoint):
程序执行过程中明确的点,如方法的调用或特定的异常被抛出。

通知(Advice):
在特定的连接点,AOP框架执行的动作。各种类型的通知包括“around”、“before”和“throws”通知。通知类型将在下面讨论。许多AOP框架包括Spring都是以拦截器做通知模型,维护一个“围绕”连接点的拦截器链。Spring中定义了四个advice:
BeforeAdvice, AfterAdvice, ThrowAdvice和DynamicIntroductionAdvice

切入点(Pointcut):
指定一个通知将被引发的一系列连接点的集合。AOP框架必须允许开发者指定切入点:例如,使用正则表达式。
Spring定义了Pointcut接口,用来组合MethodMatcher和ClassFilter,可以通过名字很清楚的理解,
MethodMatcher是用来检查目标类的方法是否可以被应用此通知,而ClassFilter是用来检查Pointcut是否应该应用到目标类上

引入(Introduction): 添加方法或字段到被通知的类。
Spring允许引入新的接口到任何被通知的对象。例如,你可以使用一个引入使任何对象实现
IsModified接口,来简化缓存。Spring中要使用Introduction,
可有通过DelegatingIntroductionInterceptor来实现通知,通过DefaultIntroductionAdvisor来配置Advice和代理类要实现的接口

目标对象(Target Object):
包含连接点的对象。也被称作被通知或被代理对象。

AOP代理(AOP Proxy): AOP框架创建的对象,包含通知。
在Spring中,AOP代理可以是JDK动态代理或者CGLIB代理。

织入(Weaving):
组装方面来创建一个被通知对象。这可以在编译时完成(例如使用AspectJ编译器),也可以在运行时完成。Spring和其他纯Java
AOP框架一样,在运行时完成织入。

   <groupId>org.springframework.boot</groupId>   <artifactId>spring-boot-starter-web</artifactId>
如何使用Spring AOP

可以通过配置文件或者编程的方式来使用Spring AOP。

  • 配置可以通过xml文件来进行,大概有四种方式:
    (1)配置ProxyFactoryBean,显式地设置advisors, advice, target等
    (2)配置AutoProxyCreator,这种方式下,还是如以前一样使用定义的bean,但是从容器中获得的其实已经是代理对象
    (3)通过<aop:config>来配置
    (4)通过<aop:
    aspectj-autoproxy>来配置,使用AspectJ的注解来标识通知及切入点

  • 也可以直接使用ProxyFactory来以编程的方式使用Spring
    AOP,通过ProxyFactory提供的方法可以设置target对象,
    advisor等相关配置,最终通过 getProxy()方法来获取代理对象

开发环境调试

spring-boot-maven-plugin

json接口开发

@RestController

@RequestMapping

自定义filter

@Configuration

@Bean

自定义配置文件

@Component

@Value(“${asd.sdf}”)

1.3spring cloud

基于spring
boot开发,解决微服务架构中的服务治理而提供的开发框架。是一系列框架的有序集合,简化了分布式基础设施的开发,如发现注册,配置中心,消息总线,负载均衡,断路器,数据监控等。

2 Spring bean的作用域

<bean=“” class=“” scope=“”/>

2.1 singleton单例 缺省作用域

容器中只会存在一个共享的bean实例,无论多少个bean引用他,始终指向一个对象。

2.2 prototype原型

每次通过spring容器获取的原型定义的bean时,容器都会创建一个新的bean实例。

2.3 request

不同的http request产生不同的bean,该bean只在当前request有效。

2.4 session

不同的http session产生不同的bean,该bean仅在当前session有效。

2.5 global session

在一个全局的http session中,容器会返回该bean的同一个实例,仅在portlet
context时有效

3 Spring bean的生命周期

Spring容器可以管理singleton作用域下的bean生命周期

而对于prototype作用域的bean,只负责创建,而不再跟踪其生命周期

4 spring bean实例化顺序

实例化bean对象

设置bean属性

检验aware相关接口并设置相关依赖

Beanpostprocessor前置处理

检查是否是initbean决定是否调用afterpropertiesset

检查是否配置有init-method

Beanpostprocessor后置处理

注册destruction相关回调接口

使用中

检查是否有disposablebean接口

检查是否有destroy方法

相关文章