Nivelle 开拓视野冲破艰险看见世界 身临其境贴近彼此感受生活

spring知识点

2018-08-24

核心知识点

配置方式

  • xml配置方式
  • 注解方式
  • java类方式
\ xml 注解 Java类
bean定义 xmlz中bean元素 @Component 在标注了@Configuration的java类中,在类的方法上标注@Bean定义bean
bean名称 通过的id活name属性定义 通过注解的value属性定义 通过@Bean的name属性定义,如@Bean(“userdao”)
bean注入 通过子元素或者p命名空间的动态属性注入 @Autowired按照类型匹配注入,@qualifier按名称,@Resource(byName->byType->反射) 1.方法出通过@Autowired方法入参绑定的bean;2.通过调用配置类的@bean方法进行注入
生命过程方法 的init-method和destory-method方法实现 @PostConstruct 和 @PreDestory @Bean 的initMethod或destoryMethod
bean作用范围 scope @scope @Scope
bean延迟初始化 的lazy-init @Lazy @Lazy

注入方式

  • 属性注入

Spring首先会调用bean的默认构造函数实例化bean对象,然后再通过反射的方法来调用set方法来注入属性值。 属性注入要求bean提供一个默认的构造函数,并且得为需要注入的属性提供set方法。

  • 构造函数注入

构造函数注入是除属性注入之外的另一种常用的注入方式,它保证一些必要的属性在Bean实例化时就得到了设置,并在实例化后就可以使用。使用构造函数注入的前提是:bean必须提供带参的构造函数。

  • 工厂方法注入

工厂方法是应用中被经常使用的设计模式,也是控制反转和单实例设计思想的主要实现方法。

事件机制

ApplicationContext事件机制是观察者设计模式的实现,通过ApplicationEvent类和ApplicationListener接口,可以实现ApplicationContext事件处理。如果容器中有一个ApplicationListener Bean,每当ApplicationContext发布ApplicationEvent时,ApplicationListener Bean将自动被触发。

  • ApplicationEvent:容器事件,必须由ApplicationContext发布
  • pplicationListener:监听器,可由容器中的任何监听器Bean担任

如果Bean想发布事件,则Bean必须获得其容器的引用。如果程序中没有直接获取容器的引用,则应该让Bean实现ApplicationContextAware或者BeanFactoryAware接口,从而可以获得容器的引用。

spring的内置事件
  • ContentRefreshedEvent:ApplicationContext容器初始化或刷新时触发该事件。此处的初始化是指:所有的Bean被成功装载,后处理Bean被检测并激活,所有Singleton Bean 被预实例化,ApplicationContext容器已就绪可用
  • ContextStartedEvent:当使用ConfigurableApplicationContext(ApplicationContext的子接口)接口的start()方法启动ApplicationContext容器时触发该事件。容器管理声明周期的Bean实例将获得一个指定的启动信号,这在经常需要停止后重新启动的场合比较常见
  • ContextClosedEvent:当使用ConfigurableApplicationContext接口的close()方法关闭ApplicationContext时触发该事件
  • ContextStoppedEvent:当使用ConfigurableApplicationContext接口的stop()方法使ApplicationContext容器停止时触发该事件。此处的停止,意味着容器管理生命周期的Bean实例将获得一个指定的停止信号,被停止的Spring容器可再次调用start()方法重新启动
  • RequestHandledEvent : Web相关事件,只能应用于使用DispatcherServlet的Web应用。在使用Spring作为前端的MVC控制器时,当Spring处理用户请求结束后,系统会自动触发该事件。

spring事务

定义: Spring 事务管理分为编码式和声明式的两种方式。编程式事务指的是通过编码方式实现事务;声明式事务基于AOP,将具体业务逻辑与事务处理解耦。声明式事务管理使业务代码逻辑不受污染,因此在实际使用中声明式事务用的比较多。声明式事务有两种方式,一种是在配置文件(xml)中做相关的事务规则声明,另一种是基于@Transactional 注解的方式。

实现机制: 在应用系统调用声明@Transactional 的目标方法时,Spring Framework 默认使用 AOP 代理,在代码运行时生成一个代理对象,根据@Transactional 的属性配置信息,这个代理对象决定该声明@Transactional 的目标方法是否由拦截器 TransactionInterceptor 来使用拦截,在 TransactionInterceptor 拦截时,会在在目标方法开始执行之前创建并加入事务,并执行目标方法的逻辑, 最后根据执行情况是否出现异常,利用抽象事务管理器AbstractPlatformTransactionManager 操作数据源 DataSource 提交或回滚事务

要点:

  1. @Transactional 只能应用到 public 方法才有效
  2. 在 Spring 的 AOP 代理下,只有目标方法由外部调用,目标方法才由 Spring 生成的代理对象来管理,这会造成自调用问题。若同一类中的其他没有@Transactional 注解的方法内部调用有@Transactional 注解的方法,有@Transactional 注解的方法的事务被忽略,不会发生回滚。 这两个问题@Transactional 注解只应用到 public 方法和自调用问题,是由于使用 Spring AOP 代理造成的。为解决这两个问题,使用 AspectJ 取代 Spring AOP 代理。
  3. “proxy-target-class” 属性值来控制是基于接口的还是基于类的代理被创建。 <tx:annotation-driven transaction-manager=“transactionManager” proxy-target-class=“true”/> 注意:proxy-target-class属性值决定是基于接口的还是基于类的代理被创建。如果proxy-target-class 属性值被设置为true,那么基于类的代理将起作用(这时需要cglib库)。如果proxy-target-class属值被设置为false或者这个属性被省略,那么标准的JDK 基于接口的代理。
  4. 注解@Transactional cglib与java动态代理最大区别是代理目标对象不用实现接口,那么注解要是写到接口方法上,要是使用cglib代理,这是注解事物就失效了,为了保持兼容注解最好都写到实现类方法上。
  5. Spring团队建议在具体的类(或类的方法)上使用 @Transactional 注解,而不要使用在类所要实现的任何接口上。在接口上使用 @Transactional 注解,只能当你设置了基于接口的代理时它才生效。因为注解是 不能继承的,这就意味着如果正在使用基于类的代理时,那么事务的设置将不能被基于类的代理所识别,而且对象也将不会被事务代理所包装。

AOP 和 IOC

常用注解

  • @DependsOn:该注解用于声明当前bean依赖于另外一个bean。所依赖的bean会被容器确保在当前bean实例化之前被实例化。
  • @Scope:默认是单例模式,即scope=”singleton”。另外scope还有prototype、request、session、global session作用域。
  • @Transactional
属性 作用
name 当在文件中配置多个TranactionManager,可以用该属性指定选择哪个事务管理器
propagation 事务的传播行为,默认值为 REQUIRED。
isolation 事务的隔离度,默认值采用 DEFAULT。使用数据库设置的隔离级别 ( 默认 ) ,由 DBA 默认的设置来决定隔离级别 .
timeout 事务的超时时间,默认值为-1。如果超过该时间限制但事务还没有完成,则自动回滚事务。
read-only 指定事务是否为只读事务,默认值为 false;为了忽略那些不需要事务的方法,比如读取数据,可以设置 read-only 为 true。
no-rollback- for 抛出 no-rollback-for 指定的异常类型,不回滚事务。

相关文章

上一篇 spring生命周期

评论