木木临夕

博客园 首页 新随笔 联系 订阅 管理
Spring学习笔记
1.Spring的特点
(1)轻量级:Spring 是非侵入性的 - 基于 Spring 开发的应用中的对象可以不依赖于 Spring 的 API 依赖注入。
(2)(DI --- dependency injection、IOC)。
(3)面向切面编程(AOP --- aspect oriented programming) 。
(4)容器: Spring 是一个容器, 因为它包含并且管理应用对象的生命周期。 
(5)框架 :Spring 实现了使用简单的组件配置组合成一个复杂的应用,在 Spring 中可以使用 XML 和 Java 注解组合这些对象 。
(6)一站式:在 IOC 和 AOP 的基础上可以整合各种企业应用的开源框架和优秀的第三方类库 (实际上 Spring 自身也提供了展现层的 SpringMVC 和 持久层的 Spring JDBC)。
2.Spring的功能
(1)Spring 容器提供了IOC机制,可以创建对象以及管理对象之间的调用关系,避免了硬编码造成的程序耦合。
(2)Spring 提供了AOP(面向切面编程方式)功能,可以实现很多特定功能声明式事务控制处理。
(3)Spring对JDBC进行了轻量级的封装,可以更加灵活的去操作数据库 。
(4)Spring提供了MVC设计模式的解决方案 
(5)Spring提供了文件上传、定时器等常用工具类 。
(6)Spring提供了对于其他优秀框架的支持(如:Struts、Hibernate、MyBatis、Quartz等)。

3.Spring体系结构 

 
 1.core container
    a.beans与core 它们提供spring框架最基本功能,包含ioc与di。
    b.context 上下文对象,基于beans与cores。
    c.spel它是spring提供的一个表达式语言。
 2.Data access/integration
    d.数据访问。
    e.集成。
 3.Web
    f.Spring本身提供spring mvc。
    g.也可以与其它的web层进行集成。
 4.AOP
    h.AOP大部分情况下是使用动态代理来实现的。
 5.Test
    i.使用spring可以方便的进行测试。

Spring的jar包下载

Spring的官网:spring.io
本次学习使用的是spring4.2.4
 
spring3.0.2版本后,不在提供依赖jar
 
其中:docs 存在API和规范文档
          libs 开发jar
          schema 开发过程中需要的xmlschema约束
4.总结spring使用步骤
    1.在applicationContext.xml文件中配置bean
    2.创建一个AppliCationContext对象
    ApplicationContext它是BeanFactory的一个子接口,我们在使用时使用的是AppliCationContext的实现类ClassPathXmlApplicationContext
   
    可以通过getBean(配置文件中id名称)来获取指定的对象。
 

5.Bean获取与实例化

ApplicationContext与BeanFactory关系
ApplicationContext它是扩展BeanFactory接口。
BeanFactory它采取延迟加载的方案,只有真正在getBean时才会实例化Bean
 
在开发中我们一般使用的是ApplicationContext,真正使用的是其实现类,
FileSystemXmlAppliCationContext 根据文件路径获取
ClassPathXmlApplicationContext  根据类路径获取
AppliCationContext它会在配置文件加载时,就会初始化Bean,并且ApplicationContext它提供不同的应用层的Context实现。例如在web开发中可以使用WebApplicationContext.
 
Bean的实例化方式
1.无参数构造
对于这种方式,注意Bean类中必须提供无参数构造。
 
2.静态工厂方法
需要创建一个工厂类,在工厂类中提供一个static返回bean对象的方法就可以。
 
3.实例工厂方法
需要创建一个工厂类,在工厂类中提供一个非static的创建bean对象的方法,在配置文件中需要将工厂配置,还需要配置bean
每一个类实现了Bean的规范才可以由Spring来接管,那么Bean的规范是什么呢?
  • 必须是个公有(public)类
  • 有无参构造函数
  • 用公共方法暴露内部成员属性(getter,setter)
实现这样规范的类,被称为Java Bean。即是一种可重用的组件。
Spring框架,通过以下方式,决定如何初始化容器:
方式一:Spring通过扫描指定包中的类,通过类上的注解,决定容器中,是否初例化该对象
方式二:XML添加
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="user" value="${jdbc.user}"></property>
</bean>
//如上bean标签的作用,就是实例化对象,上述等价如下java代码
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSouce.user = ${jdbc.user}
 
Bean的作用域
在bean声明时它有一个scope属性,它是用于描述bean的作用域。
可取值有:
    singleton:单例 代表在spring ioc容器中只有一个Bean实例 (默认的scope)
    prototype多例 每一次从spring容器中获取时,都会返回一个新的实例
    request 用在web开发中,将bean对象request.setAttribute()存储到request域中
    session 用在web开发中,将bean对象session.setAttribute()存储到session域中
在开发中常用的值是singleton与prototype
 
Bean的生命周期
1.instantiate bean对象实例化
2.populate properties 封装属性
3.如果Bean实现BeanNameAware执行setBeanName
4.如果Bean实现BeanFactoryAwar或ApplicationContextAwar设置工厂setBeanFactory或上下文对象setApplicationContext
5.如果存在类实现BeanPostProcessor(后处理Bean),执行postProcessBeforeInitialization
6.如果Bean实现InitializingBean执行afterPropertiesSet
7.调用自定义的init-method方法
8.如果存在类实现BeanPostProcessor(处理Bean),执行postProcessAfterInitialization
9.执行业务处理
10.如果Bean实现DisposableBean执行destroy
11.调用自定义的destroy-method
 
对于bean的生命周期方法:
    第三步与第四步是让Bean了解spring容器。
    第五步与第八步 可以针对指定的Bean进行功能增强,这时一般会使用动态代理.
    第六步与第十步:通过实现指定的接口来完成init与destroy操作
    但是在开发中一般不使用第6步与第10步,原因是我们可以使用第7步与第11步来完成。
    第7步与第11步的初始化与销毁操作它无耦合,推荐使用的。但是必须在配置文件中指定初始化与销毁的方法
  
总结:
    对于bean的生命周期,我们需要关注的主要有两个方法:
        1.增强bean的功能可以使用后处理Bean, BeanPostProcessor
        2.如果需要初始化或销毁操作我们可以使用init-method  destroy-method
        注意:destroy-method只对scope=singleton有效果。
6.DI(Dependency Injection,依赖注入)/IoC (Inversion of Control)控制反转
IoC (Inversion of Control),控制反转,用白话来讲,就是由容器控制程序之间的关系,而非传统实现中,由程序代码直接操控。这也就是所谓“控制反转”的概念所在:控制权由应用代码中转到了外部容器,控制权的转移,是所谓反转。
相对IoC而言“依赖注入DI (Dependency Injection)”的确更加准确的描述了这种古老而又时兴的设计理念。从名字上理解,所谓依赖注入,即组件之间的依赖关系由容器在运行期决定,形象的来说,即由容器动态的将某种依赖关系注入到组件之中。
注意:依赖注入和控制反转是对同一件事情的不同描述,从某个方面讲,就是它们描述的角度不同,依赖注入是从应用程序的角度在描述,应用程序依赖容器创建并注入它所需要的外部资源,控制反转从容器的角度在描述,容器控制应用程序,由容器反向的向应用程序注入应用程序所需要的外部资源。
1) 应用程序依赖 spring 注入所需要的对象
2) setter 注入:在配置文件中将接口的实现配置为 bean 在应用程序中注入
bean
例如:
在配置文件中
<bean name=”dao” class=”daoImpl”>
<property name=”cc” ref=”cc”>
</bean>
在应用程序中
Public DBDAO dao ;
Public void setDao(DBDAO dao){
This.dao = dao;
}
3) 构造器注入
<constructor-arg>
4) ref 表示参照其它的 bean
在参照的过程中一定要注意死循环
5) 自动装配-----------〉no
自动装配根据名字来匹配相应的 bean 尽量不要去自动装配
6) lookup 注入
7)singleton:单例模式是整个的 jvm 中只有一个实例,spring 的 singleton 是指在 spring 的容器中只有一个实例,一个生命周期中只有一个实例
8)DI依赖注入 的优点:
1.程序被动等待,强化面向接口编成
2.切断了对象或组件之间的联系,使程序的结构更加松散,运行和维护更加简单
7.AOP(Aspect Oriented Programming,面向切面编程)
     1.含义:在面向对象编程(oop)思想中,我们将事物纵向抽成一个个的对象。而在面向切面编程中,我们将一个个的对象某些类似的方面横向抽成一个切面,对这个切面进行一些如权限控制、事物管理,记录日志等公用操作处理的过程就是面向切面编程的思想。AOP 底层是动态代理,如果是接口采用 JDK 动态代理,如果是类采用CGLIB 方式实现动态代理。在应用 AOP 编程时, 仍然需要定义公共功能, 但可以明确的定义这个功能在哪里, 以什么方式应用, 并且不必修改受影响的类. 这样一来,横切关注点就被模块化到特殊的对象(切面)里。
    2.AOP的优点:每个事物逻辑位于一个位置, 代码不分散, 便于维护和升级;业务模块更简洁, 只包含核心业务代码。
    3.AOP的实现原理
        AOP依赖于动态代理模式的实现。其中重要的组成部分包括:连接点(Joinpoint)、通知(Advice)、切入点(Pointcut)、引入(Introduction)、目标对象(Target Object)、AOP 代理(AOP Proxy)和织入(Weaving);AspectJ:Java 社区里最完整最流行的 AOP 框架,提供了几种常见的通知类型参考:前置通知(Before advice)、返回后通知(After returning advice)、抛出异常后通知(After throwing advice)、后通知(After (finally) advice)、环绕通知(Around Advice)。环绕通知的功能最为强大,它可以实现其他所有类型通知的功能,还能够决定连接点方法的执行方式、是否执行、是否伪造返回值、是否伪造参数等,Spring中可以使用Schema风格的XML配置和AspectJ方式配置两个风格对AOP进行配置,功能类似。
4.利用XML配置装配AOP
利用XML配置进行AOP组件的声明装配:
注意:当使用 XML 声明切面时, 需要在 <beans> 根元素中导入 aop Schema。 
          在 Bean 配置文件中, 所有的 Spring AOP 配置都必须定义在 <aop:config> 元素内部,对于每个切面而言, 都要创建一个 <aop:aspect> 元素来为具体的切面实现引用后端 Bean 实例。
          一个application context可以包含多个 <aop:config>, 一个 <aop:config> 可以包含pointcut,advisor和aspect元素(注意它们必须按照这样的顺序进行声明)。
          切面 Bean 必须有一个标示符, 供 <aop:aspect> 元素引用。
AOP命名空间及Schema示例
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:jpa="http://www.springframework.org/schema/data/jpa"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans  http://www.springframework.org/schema/beans/spring-beans.xsd
              http://www.springframework.org/schema/data/jpa  http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
              http://www.springframework.org/schema/tx  http://www.springframework.org/schema/tx/spring-tx.xsd
              http://www.springframework.org/schema/context  http://www.springframework.org/schema/context/spring-context.xsd
              http://www.springframework.org/schema/aop  http://www.springframework.org/schema/aop/spring-aop.xsd">
切点切面的配置,利用Spring的AOP来重新实现代理模式的应用示例。示例:FBI监视嫌疑人的qq聊天,Msn情况。
定义切点和切面类并将其加入Spring容器:
Man.java类
public class Man {
 
       private String name;
       public String getName() {
              return name;
       }
       public void setName(String name) {
              this.name = name;
       }
}
 
FBI.java类
 
public class Man {
       private String name;
       public String getName() {
              return name;
       }
       public void setName(String name) {
              this.name = name;
       }
       
       public void qq() {
              
              System.out.println("我在聊qq");
              
       }
       
       public void msn() {
              
              System.out.println("我在聊msn");
              
       }
}
加入Spring容器
 
<bean id="man" class="com.sitech.springAop.Man" p:name="XiaoMing">
<bean id="fbi" class="com.sitech.springAop.FBI">
 
配置切入点并进行织入装配
 
<aop:config>
    <aop:pointcut id="manPointcut" expressions="execution(*com.sitech.springAop.Man.*(..))" />
    <aop:aspect  id="beroreExample" ref="fbi">
        <aop:before pointcut-ref="manPointcut" method="before" />
    </aop:aspect>
</aop:config>
 
1.配置切入点,expression指明切入点表达式,表明切入的目标连接点
2.声明通知(before说明声明的是前置通知),说明绑定的切入点和通知方法
注意:aop:config是AOP配置的根标签,所有的AOP配置都在它的内部
 
测试程序
 
public class AopTest {
       
       public static void main(String[] args) {
              
              ApplicationContext context =  new  ClassPathXmlApplicationContext("applicationContext.xml");
              Man man = context.getBean("man",Man.class);
              man.qq();
              man.msn();
       }
}
 
从上例可以看到,Spring中使用切入点表达式来明确切点和切面增强的装配关系,Spring AOP 支持在切入点表达式中使用如下的格式:
 
方法
说明
execution
匹配方法执行的连接点,这是将会用到的Spring的最主要的切入点指定者
within
限定匹配特定类型的连接点(在匹配的类型中定义的方法的执行)
this
限定实现特定接口的代理对象连接点
target
限定实现特定接口的目标对象(非代理对象)连接点
args
限定匹配特定的连接点,其中参数是指定类型的实例
@target
限定匹配特定的连接点,其中实际执行的对象本身(属性变量上)已经有指定类型的注解
@args
限定匹配特定的连接点,其中实际传入参数的运行时类型有指定类型的注解
@within
限定匹配特定的连接点,其中连接点所在类型已指定注解
@annotation
限定匹配特定的连接点,其中连接点的主题有某种给定的注解
bean
beanid匹配,匹配的bean中全部方法作连接点,可以使用Beanidname进行匹配,并且可使用通配符“*”
 
在切入点表达式中描述类型、方法时可以使用通配符进行多目标匹配: 
 
通配符
说明
*
匹配任何数量字符
..
匹配任何数量字符的重复,如在类型模式中匹配任何数量子包;而在方法参数模式中匹配任何数量参数
+
匹配指定类型的子类型;仅能作为后缀放在类型模式后边
示例:
表达式
匹配
java.lang.String
匹配String类型
java.*.String
匹配java包下的任何直接子包下的String类型如java.lang.String,但不匹配java.lang.ss.String 
java..* 
匹配java包及任何子包下的任何类型java.lang.Stringjava.lang.annotation.Annotation 
java.lang.*ing
匹配任何java.lang包下的以ing结尾的类型
java.lang.Number+
匹配java.lang.Number的子类型;  如匹配java.lang.Integer,也匹配java.math.BigInteger
(1)具体的切入点匹配表达式类型:匹配类型部分使用如下方式匹配(?表示可选):
方式:注解? 类的全限定名字  
注意:注解:可选,类型上持有的注解,如@Deprecated;
     类的全限定名:必填,可以是任何类全限定
(2)匹配方法部分使用如下方式匹配:      
方式:注解? 修饰符? 返回值类型 类型声明?方法名(参数列表) 异常列表? 
注意:注解: 可选,方法上持有的注解,如@Deprecated 修饰符: 可选,如public、protected 
     返回值类型: 必填,可以是任何类型模式;“*”表示所有类型     
     类型声明: 可选,可以是任何类型模式 方法名: 必填,可以使用“*”进行模式匹配 
     参数列表(以,分割):“()”表示方法没有任何参数;“(..)”表示匹配接受任意个参数的方法,“(..,java.lang.String)”表示匹配接受java.lang.String类型的参数结束,且其前边可以接受有任意个参数的方法;
                        “(java.lang.String,..)” 表示匹配接受java.lang.String类型的参数开始,且其后边可以接受任意个参数的方法;
                        “(*,java.lang.String)” 表示匹配接受java.lang.String类型的参数结束,且其前边接受有一个任意类型参数的方法 
     异常列表: 可选,以“throws 异常全限定名列表”声明,异常全限定名列表如有多个以“,”分割,如throws java.lang.IllegalArgumentException, java.lang.ArrayIndexOutOfBoundsException 
 
 
posted on 2019-01-16 13:33  木木临夕  阅读(451)  评论(0编辑  收藏  举报