• 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
  • 相关阅读:
    工厂模式
    Bootstrap 日历
    处理乱码
    Eclipse常用快捷键
    C#_XML与Object转换
    jQuery选择函数
    Bootstrap如何正确引用字体图标
    js上拉加载、下拉刷新的插件
    js通用对象数组冒牌排序
    关于js跨域
  • 原文地址:https://www.cnblogs.com/orco/p/6272576.html
Copyright © 2020-2023  润新知