Spring4笔记

Spring提供了两种类型的IOC容器实现,BeanFactory和ApplicationContext,前者面向Spring框架本身,后者变相开发者。

ApplicationContext提供了两种实现:

  ClassPathXmlApplicationContext:从 类路径下加载配置文件

  FileSystemXmlApplicationContext: 从文件系统中加载配置文件

ConfigurableApplicationContext 扩展于 ApplicationContext,新增加两个主要方法:refresh() 和 close(), 让 ApplicationContext 具有启动、刷新和关闭上下文的能力

<constructor-arg> 中没有 name 属性

若字面值中包含特殊字符,可以使用 <![CDATA[]]> 把字面值包裹起来。

自动装配:byType、byName、constructor(通过构造器自动装配,不推荐使用)

Spring 允许继承 bean 的配置, 被继承的 bean 称为父 bean. 继承这个父 Bean 的 Bean 称为子 Bean
子 Bean 从父 Bean 中继承配置, 包括 Bean 的属性配置
子 Bean 也可以覆盖从父 Bean 继承过来的配置
父 Bean 可以作为配置模板, 也可以作为 Bean 实例. 若只想把父 Bean 作为模板, 可以设置 <bean> 的abstract 属性为 true, 这样 Spring 将不会实例化这个 Bean
并不是 <bean> 元素里的所有属性都会被继承. 比如: autowire, abstract 等.
也可以忽略父 Bean 的 class 属性, 让子 Bean 指定自己的类, 而共享相同的属性配置. 但此时 abstract 必须设为 true
继承Bean配置
Spring 允许用户通过 depends-on 属性设定 Bean 前置依赖的Bean,前置依赖的 Bean 会在本 Bean 实例化之前创建好
如果前置依赖于多个 Bean,则可以通过逗号,空格或的方式配置 Bean 的名称
依赖Bean配置

Bean的作用于:sigleton(单例)、prototype(原型)、request和session不常用。

Spring 提供了一个 PropertyPlaceholderConfigurer 的 BeanFactory 后置处理器, 这个处理器允许用户将 Bean 配置的部分内容外移到属性文件中.

可以在 Bean 配置文件里使用形式为 ${var} 的变量, PropertyPlaceholderConfigurer 从属性文件里加载属性, 并使用这些属性来替换变量

命名空间:

  beans:基本的,需要有

  util:如实例化一个list这种的时候需要

  p:spring2.5之后加入的,简化属性注入

  context:如引用外部文件的时候需要(<context:property-placeholder location="classpath:db.properties"/>  ,spring2.5之后提供的,简化2.0)

Bean的生命周期:

IOC 容器中 Bean 的生命周期方法:

Spring IOC 容器可以管理 Bean 的生命周期, Spring 允许在 Bean 生命周期的特定点执行定制的任务.

Spring IOC 容器对 Bean 的生命周期进行管理的过程:

    通过构造器或工厂方法创建 Bean 实例
    为 Bean 的属性设置值和对其他 Bean 的引用
    调用 Bean 的初始化方法
    Bean 可以使用了
    当容器关闭时, 调用 Bean 的销毁方法

在 Bean 的声明里设置 init-method 和 destroy-method 属性, 为 Bean 指定初始化和销毁方法.

创建 Bean 后置处理器:

  Bean 后置处理器允许在调用初始化方法前后对 Bean 进行额外的处理.
  Bean 后置处理器对 IOC 容器里的所有 Bean 实例逐一处理, 而非单一实例. 其典型应用是: 检查 Bean 属性的正确性或根据特定的标准更改 Bean 的属性.
  对Bean 后置处理器而言, 需要实现 BeanPostProcessor 接口. 在初始化方法被调用前后, Spring 将把每个 Bean 实例分别传递给上述接口的两个方法.

添加 Bean 后置处理器后 Bean 的生命周期:

  Spring IOC 容器对 Bean 的生命周期进行管理的过程:
  通过构造器或工厂方法创建 Bean 实例
  为 Bean 的属性设置值和对其他 Bean 的引用
  将 Bean 实例传递给 Bean 后置处理器的 postProcessBeforeInitialization 方法
  调用 Bean 的初始化方法
  将 Bean 实例传递给 Bean 后置处理器的 postProcessAfterInitialization方法
  Bean 可以使用了
  当容器关闭时, 调用 Bean 的销毁方法

@Component: 基本注解, 标识了一个受 Spring 管理的组件
@Respository: 标识持久层组件
@Service: 标识服务层(业务层)组件
@Controller: 标识表现层组件

<context:component-scan> 元素还会自动注册 AutowiredAnnotationBeanPostProcessor 实例, 该实例可以自动装配具有 @Autowired 和 @Resource 、@Inject注解的属性.

默认情况下, 当 IOC 容器里存在多个类型兼容的 Bean 时, 通过类型的自动装配将无法工作. 此时可以在 @Qualifier 注解里提供 Bean 的名称. Spring 允许对方法的入参标注 @Qualifiter 已指定注入 Bean 的名称

@Qualifier可以放在bean的属性上面,也可以放在其set方法上面,也可以放在参数前面,比如set方法的参数前面

Spring 还支持 @Resource 和 @Inject 注解,这两个注解和 @Autowired 注解的功用类似,建议使用 @Autowired 注解

使用动态代理也可以实现aop,就是麻烦了点

该配置的作用是,使aspectJ注解起作用,为匹配的类自动生成代理对象。

AspectJ 支持 5 种类型的通知注解:
    @Before: 前置通知, 在方法执行之前执行
    @After: 后置通知, 在方法执行之后执行
    @AfterRunning: 返回通知, 在方法返回结果之后执行
    @AfterThrowing: 异常通知, 在方法抛出异常之后
    @Around: 环绕通知, 围绕着方法执行

@Before,前置通知:

@After,后置通知:在目标方法执行之后(无论是否发生异常),执行的通知,在后置通知中还不能访问目标方法执行的结果,可以在结果通知中获得。

//@execution("execution(public int com.atguigu.spring.aop.ArithmeticCalculator.*(..))")

@AfterRunning  &  @AfterThrowing

异常通知,这里需要说明,Exception可以换成别的异常,如空指针异常,如果出发的是别的异常,则不会走异常通知

/**
 * 环绕通知需要携带 ProceedingJoinPoint 类型的参数. 
 * 环绕通知类似于动态代理的全过程: ProceedingJoinPoint 类型的参数可以决定是否执行目标方法.
 * 且环绕通知必须有返回值, 返回值即为目标方法的返回值
 */
@Around("execution(public int com.atguigu.spring.aop.ArithmeticCalculator.*(..))")
public Object aroundMethod(ProceedingJoinPoint pjd){
    
    Object result = null;
    String methodName = pjd.getSignature().getName();
    
    try {
        //前置通知
        System.out.println("The method " + methodName + " begins with " + Arrays.asList(pjd.getArgs()));
        //执行目标方法
        result = pjd.proceed();
        //返回通知
        System.out.println("The method " + methodName + " ends with " + result);
    } catch (Throwable e) {
        //异常通知
        System.out.println("The method " + methodName + " occurs exception:" + e);
        throw new RuntimeException(e);
    }
    //后置通知
    System.out.println("The method " + methodName + " ends");
    
    return result;
}
环绕通知

 如果有两个切面的话,就有切面的优先级问题,可以在@Aspect上面加个@order(1)来排优先级,值越小,优先级越高

定义一个方法,用来声明切入点表达式:

如果是在其他包,其他类里面的@Before这种通知里引用,需要加上全类名.方法名。

基于xml配置的方式实现aop

声明式事务:

1、

<!-- 配置事务管理器 -->
<bean id="transactionManager" 
    class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"></property>
</bean>

<!-- 启用事务注解 -->
<tx:annotation-driven transaction-manager="transactionManager"/>

2、在对应的数据方法上面,加上 @Transactional ,这样基本的事务可以了,之后就是根据需要,在这个标签里面加一些属性了。

事务的传播行为(propagation):

常用的有required(用已经有的事务,默认的)以及required_new(新建一个事务或者是用自己的事务,就是跟上个事务没关系了,如果出错,只回滚自己的事务,上个不回滚)

a 、b方法有事务,a方法调用b时,a是用b的事务还是新建一个?

买两本书,checkout有事务,purchase也有,

如果传播行为是required,则整个过程可以看成只有一个事务,事务过程中只要出错,就回滚所有

如果传播行为是required_new,purchase_1执行政策,purchase_2异常,则只回滚到purchase_2 之前,purchase_1已经成功了(required_new 在 purchase 方法上)

    //添加事务注解
    //1.使用 propagation 指定事务的传播行为, 即当前的事务方法被另外一个事务方法调用时
    //如何使用事务, 默认取值为 REQUIRED, 即使用调用方法的事务
    //REQUIRES_NEW: 事务自己的事务, 调用的事务方法的事务被挂起. 
    //2.使用 isolation 指定事务的隔离级别, 最常用的取值为 READ_COMMITTED
    //3.默认情况下 Spring 的声明式事务对所有的运行时异常进行回滚. 也可以通过对应的
    //属性进行设置. 通常情况下去默认值即可. 
    //4.使用 readOnly 指定事务是否为只读. 表示这个事务只读取数据但不更新数据, 
    //这样可以帮助数据库引擎优化事务. 若真的事一个只读取数据库值的方法, 应设置 readOnly=true
    //5.使用 timeout 指定强制回滚之前事务可以占用的时间,如果一个操作超过3秒,就强制回滚。然后报    //timeout异常。
    //6.noRollbackFor通常不设置,默认就好
//    @Transactional(propagation=Propagation.REQUIRES_NEW,
//            isolation=Isolation.READ_COMMITTED,
//            noRollbackFor={UserAccountException.class})
    @Transactional(propagation=Propagation.REQUIRES_NEW,
            isolation=Isolation.READ_COMMITTED,
            readOnly=false,
            timeout=3)//单位:s
    @Override
    public void purchase(String username, String isbn) {

基于xml的方式配置事务:

<!-- 1. 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"></property>
</bean>

<!-- 2. 配置事务属性 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
    <tx:attributes>
        <!-- 根据方法名指定事务的属性,一般是将get这种只获取的设置为read-only,propagation一般默认即可,不需要配置 -->
        <tx:method name="purchase" propagation="REQUIRES_NEW"/>
        <tx:method name="get*" read-only="true"/>
        <tx:method name="find*" read-only="true"/>
        <tx:method name="*"/>
    </tx:attributes>
</tx:advice>

<!-- 3. 配置事务切入点, 以及把事务切入点和事务属性关联起来 -->
<aop:config>
    <aop:pointcut expression="execution(* com.atguigu.spring.tx.xml.service.*.*(..))" 
        id="txPointCut"/>
    <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>    
</aop:config>
这个博客主要是javaEE相关或者不相关的记录, hadoop与spark的相关文章我写在下面地址的博客啦~ http://www.cnblogs.com/sorco
原文地址:https://www.cnblogs.com/orco/p/6272576.html