Spring

Spring是什么

  • 是一个开源框架,为了解决企业应用开发的复杂性而创建的,现在已经不止应用于企业应用

  • 是一个轻量级的控制反转IoC和面向切面AOP的容器框架

    • 从大小与开销两方面而言都是轻量的
    • 通过IoC的技术达到松耦合的目的
    • 提供了面向切面变成的丰富支持,允许通过分离应用的业务逻辑与系统级服务进行内聚性的开发
    • 包含并管理应用对象的配置和生命周期——容器
    • 将简单的组件配置、组合成为复杂的应用——框架
  • 开发应用简单、方便、快捷

什么是框架

  • 半成品
  • 封装了特定的处理流程和控制逻辑
  • 成熟的、不断升级改进的软件

为什么使用框架

  • 软件系统日趋复杂
  • 重用度高,开发效率和质量提高
  • 需求分析更充分
  • 易于上手

IOC

IOC:控制反转,控制权的转移,应用程序本身不负责依赖对象的创建和维护,而是由外部容器负责创建和维护。

DI:依赖注入,是IOC的一种实现方式

目的:创建对象并且组装对象之间的关系

单元测试

  • 下载junit-*.jar并引入工程
  • 创建UnitTestBase类,完成对Spring配置文件的加载、销毁
  • 所有的单元测试类都继承自UnitTestBase,通过它的getBean方法获取想要得到的对象
  • 子类(具体执行单元测试的类)加注解:@RunWith(BlockJUnit4ClassRunner.class)
  • 单元测试方法加注解:@Test

Spring注入

指在启动Spring容器加载bean配置的时候,完成对变量的赋值行为

常用的两种注入方式:

  1. 设值注入

    <!-- id表示class里面类的一个实例,里面有一个名为injectionDAO的变量,ref表示引用,里面的变量就是引用的id
    这个类里面必须有一个名为injectionDAO的成员变量和set方法,会自动把下面类的实例赋值给injectionDAO -->
    <bean id="injectionService" class="com.injection.service.InjectionServiceImpl">
      <property name="injectionDAO" ref="injectionDAO"/>
    </bean>
    <!-- 被引用的变量,表示class类的一个实例 -->
    <bean id="injectionDAO" class="com.injection.dao.InjectionDAOImpl"></bean>
    
  2. 构造注入

    <!-- 与上面一样,不同点在于constructor表示类里面必须有一个构造方法,参数是injectionDAO-->
    <bean id="injectionService" class="com.injection.service.InjectionServiceImpl">
      <constructor-arg name="injectionDAO" ref="injectionDAO"/>
    </bean>
    
    <bean id="injectionDAO" class="com.injection.dao.InjectionDAOImpl"></bean>
    

Bean

作用域 scope="singleton"

  • singleton(默认):单例,指一个Bean容器中只存在一份
  • prototype:每次请求(每次使用)创建新的实例,destory方式不生效
  • request:每次http请求创建一个实例且仅在当前request内有效
  • session:同上,每次http请求创建,当前session内有效
  • global session:基于portlet的web中有效(portlet定义了global session),如果是在web中,同session

生命周期

定义

初始化

​ 两种方法:

  1. 实现org.springframework.beans.factory.InitializingBean接口,覆盖afterPropertiesSet方法

    public class ExampleInitializingBean implements InitializingBean{
      @Override
      public void afterPropertiesSet() throw Exception{
        //do
      }
    }
    
  2. 配置init-method

使用

销毁

​ 两种方式:

  1. 实现org.springframework.beans.factory.DisposableBean接口,覆盖destroy 方法

  2. 配置destroy-method

    <bean id= class= init-method="start" destroy-method="stop" ></bean>
    <!-- 调用类里面的start和stop方法 -->
    

自动装配 autowire

在不使用<constructor-arg><property> 元素的情况下自动装配相互协作的 bean 之间的关系,这有助于减少编写一个大的基于 Spring 的应用程序的 XML 配置的数量。

可以用元素的autowire属性为一个bean定义指定自动装配模式。

模式 描述
no 默认的设置,意味着没有自动装配,应该使用显式的bean引用来连线。
byName 由属性名自动装配。Spring 容器看到在 XML 配置文件中 bean 的自动装配的属性设置为 byName。然后尝试匹配,并且将它的属性与在配置文件中被定义为相同名称的 beans 的属性进行连接。
byType 由属性数据类型自动装配。Spring 容器看到在 XML 配置文件中 bean 的自动装配的属性设置为 byType。然后如果它的类型匹配配置文件中的一个确切的 bean 名称,它将尝试匹配和连接属性的类型。如果存在不止一个这样的 bean,则一个致命的异常将会被抛出。
constructor 类似于 byType,但该类型适用于构造函数参数类型。如果在容器中没有一个构造函数参数类型的 bean,则一个致命错误将会发生。

Resources 针对于资源文件的统一接口 & ResourceLoader

  • UrlResource:URL对应的资源,根据一个URL地址即可构建
  • ClassPathResource:获取类路径下的资源文件
  • FileSystemResource:获取文件系统里面的资源
  • ServletContextResource:ServletContext封装的资源,用于访问ServletContext环境下的资源
  • InputStreamResource:针对于输入流封装的资源
  • ByteArrayResource:针对于字节数组封装的资源
ResourceLoader

加载Resource的类

Bean管理的注解实现

Spring可以自动检测类并注册Bean到ApplicationContext中

为了能够检测这些类并注册相应的Bean,需要在Bean中加上

<context:component-scan base-package=""/>

使用过滤器进行自定义扫描

默认情况下,类被自动发现并注册bean的条件是:使用@Component,@Repository,@Service,@Controller注解或者使用@Component的自定义注解

还可使用use-default-filters="false"禁用自动发现与注册

  • @Component是一个通用注解,可用于任何bean
  • @Repository,@Service,@Controller是更有针对性的注解
    • @Repository通常用于注解DAO类,持久层
    • @Service通常用于注解Service类,服务层
    • @Controller通常用于Controller类,控制层
@Required(不太常用

适用于bean属性的setter方法,这个注解仅仅表示受影响的bean属性必须在配置时被填充,通过在bean定义或通过自动装配一个明确的属性值

@Autowired 自动装配(常用

可以将@Autowired注解为"传统"的setter方法

private MovieFinder movieFinder;

@Autowired
public void setMovieFinder(MovieFinder movieFinder){
  this.movieFinder = movieFinder;
}

可用于构造器或成员变量

@Autowired
private MovieFinder movieFinder; 

默认情况下,如果因找不到合适的bean将会导致autowiring失败抛出异常

每个类只能有一个构造器被标记为required=true

@Autowired的必要属性,建议使用@Required注解

public class SimpleMovieLister{
  private MovieFinder movieFinder;

  @Autowired(required=false)
  //标注required=false后,如果找不到movieFinder的bean实例也不会报抛出异常
  public void setMovieFinder(MovieFinder movieFinder){
    this.movieFinder = movieFinder;
  }
  //...
}

@Autowired不能在自定义的BeanPostProcessor或BeanFactoryPostProcessor类型应用这些注解,这些类型必须通过XML或者Spring的@Bean注解加载

@Qualifier

当按类型自动装配可能多个bean实例的情况,可以使用Spring的@Qualifier注解缩小范围(或指定唯一),也可以用于指定单独的构造器参数或方法参数

可用于注解集合类型变量

public class MovieRecommender{
  @Autowired
  @Qualifier("main")
  //如果有多个MovieCatlog的时候,可以通过@Qualifier来指定唯一
  private MovieCatalog movieCatalog;
}
  • @Autowired适用于fields,constructors,multi-argument methods,这些情况下允许在参数级别使用@Qualifier注解缩小范围
  • @Resource适用于成员变量、只有一个参数的setter方法,所以在目标是构造器或一个多参数方法时,最好的方式是使用qualifiers
基于Java的容器注解
  • @Bean标识一个用于配置和初始化一个由SpringIoC容器管理的新对象的方法,类似于XML配置文件的

  • @Configuration 指示一个类声明一个或多个@Bean方法,并且可以由Spring容器处理,以便在运行时为这些bean生成BeanDefinition和服务请求

    @Configuration
    public class AppConfig {
    
        @Bean
        public MyBean myBean() {
            // instantiate, configure and return bean ...
        }
    }
    

AOP

AOP: Aspect Oriented Programming,面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。

  • 面向切面编程是针对业务处理过程中的切面进行提取,它所面对的是处理过程中某个步骤或阶段,以获得逻辑过程中各部分之间低耦合性的隔离效果。
  • 所谓的切面,简单来说就是与业务无关,却为业务模块所共同调用的逻辑,将其封装起来便于减少系统的重复代码,降低模块的耦合度,有利用未来的可操作性和可维护性。

主要的功能:日志记录,性能统计,安全控制,事务处理,异常处理等

实现方式:

  • 预编译
    • AspectJ
  • 运行期动态代理(JDK动态代理、CGLib动态代理)
    • SpringAOP、JbossAOP

几个相关概念

名称 说明
切面Aspect 一个关注点的模块化,这个关注点可能会横切多个对象
连接点Joinpoint 程序执行过程中的某个特定的点
通知Advice 在切面的某个特定的连接点上执行的动作
切入点Pointcut 匹配连接点的断言,在AOP中通知和一个切入点表达式关联
引入Introduction 在不修改类代码的前提下,为类添加新的方法和属性
目标对象Target Object 被一个或者多个切面所通知的对象
AOP代理 AOP Proxy AOP框架创建的对象,用来实现切面契约aspect contract
织入Weaving 把切面连接到其它的应用程序类型或者对象上,并创建一个被通知的对象,分为:编译时织入、类加载时织入、执行时织入

ProxyFactoryBean

  • 创建Spring AOP代理的基本方法是使用org.springframework.aop.framewok.ProxyFactoryBean

  • 可以完全控制切入点和通知advice以及他们的顺序

  • 好处:通知和切入点也可以由IoC来管理

  • 被代理类没有实现任何接口,使用CGLIB代理,否则JDK代理

posted @ 2021-07-07 15:17  GladysChloe  阅读(51)  评论(0)    收藏  举报