Spring速查手册

Posted gustavo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring速查手册相关的知识,希望对你有一定的参考价值。

toc

介绍

Spring框架,可以解决对象创建以及对象之间依赖关系的一种框架。

主要模块

Spring Core: 基础,可以说 Spring 其他所有的功能都需要依赖于该类库。主要提供 IOC 依赖注入功能。
Spring Aspects :该模块为与AspectJ的集成提供支持。
Spring AOP :提供了面向方面的编程实现。
Spring JDBC : Java数据库连接。
Spring JMS :Java消息服务。
Spring ORM : 用于支持Hibernate等ORM工具。
Spring Web : 为创建Web应用程序提供支持。
Spring Test : 提供了对 JUnit 和 TestNG 测试的支持。

IOC

什么是SpringIOC,就是把每一个bean(实体类)与bean(实体类)之间的关系交给第三方容器进行管理。
IoC(Inverse of Control:控制反转)是一种设计思想,就是将原本在程序中手动创建对象的控制权,交由Spring框架来管理。 IoC 在其他语言中也有应用,并非 Spirng 特有。 IoC容器是Spring用来实现IoC的载体,IoC容器实际上就是个Map(key,value),Map中存放的是各种对象。
XML-(读取)->Resource-(解析)->BeanDefinition-(注册)->BeanFactory

原理


AOP

介绍

AOP(Aspect-Oriented Programming:面向切面编程)能够将那些与业务无关,却为业务模块所共同调用的逻辑或责任(例如事务处理、日志管理、权限控制等)封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可拓展性和可维护性。
Spring AOP就是基于动态代理的。

WEB

MVC

事务

Spring事务管理
编程式事务管理:这意味着你可以通过编程的方式管理事务,这种方式带来了很大的灵活性,但很难维护。
声明式事务管理:这种方式意味着你可以将事务管理和业务代码分离。你只需要通过注解或者XML配置管理事务。

事务隔离级别
TransactionDefinition 接口中定义了五个表示隔离级别的常量:
TransactionDefinition.ISOLATION_DEFAULT: 使用后端数据库默认的隔离级别,mysql 默认采用的REPEATABLE_READ隔离级别 Oracle默认采用的 READ_COMMITTED隔离级别.
TransactionDefinition.ISOLATION_READ_UNCOMMITTED: 最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读
TransactionDefinition.ISOLATION_READ_COMMITTED: 允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生
TransactionDefinition.ISOLATION_REPEATABLE_READ: 对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。
TransactionDefinition.ISOLATION_SERIALIZABLE: 最高的隔离级别,完全服从ACID的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。但是这将严重影响程序的性能。通常情况下也不会用到该级别。

事务传播行为
Spring 事务中哪几种事务传播行为?
支持当前事务的情况:
TransactionDefinition.PROPAGATION_REQUIRED: 如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。
TransactionDefinition.PROPAGATION_SUPPORTS: 如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。
TransactionDefinition.PROPAGATION_MANDATORY: 如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。(mandatory:强制性)
不支持当前事务的情况:
TransactionDefinition.PROPAGATION_REQUIRES_NEW: 创建一个新的事务,如果当前存在事务,则把当前事务挂起。
TransactionDefinition.PROPAGATION_NOT_SUPPORTED: 以非事务方式运行,如果当前存在事务,则把当前事务挂起。
TransactionDefinition.PROPAGATION_NEVER: 以非事务方式运行,如果当前存在事务,则抛出异常。
其他情况:
TransactionDefinition.PROPAGATION_NESTED: 如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于TransactionDefinition.PROPAGATION_REQUIRED。

事务控制方式

Spring 事物控制

常用的事物控制方式大致分为四种。

1、编程式事务:配置文件中有对应配置,很少用这这事物管理了

    public void transfer(final String out, final String in, final Double money) {
        /*accountDao.outMoney(out, money);
        //int i = 1/0;
        accountDao.inMoney(in, money);*/

        transactionTemplate.execute(new TransactionCallbackWithoutResult() {

            @Override
            protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
                accountDao.outMoney(out, money);
                //int i = 1/0;
                accountDao.inMoney(in, money);
            }
        });
    }
2、使用了XML配置的方式进行事物管理,但是没有使用AOP,基于TransactionProxyFactoryBean

<!-- 配置service层的代理 -->
<bean id = "taskServiceProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
    <!-- 配置目标对象 -->
    <property name = "target" ref="taskService"></property>
    <!-- 注入事务管理器 -->
    <property name = "transactionManager" ref="transactionManager"></property>
    <!-- 设置需要事务管理的方法 -->
    <property name="transactionAttributes">
        <props>
            <prop key="update*">PROPAGATION_REQUIRED</prop>
        </props>
    </property>
</bean>

@Resource(name = "taskServiceProxy")
private ITaskService taskSerivce;
3、要采用注解的方式,需要在配置文件中开启注解事务。

<!-- 开启注解事务 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
在使用时只需在对应的类上添加注解@Transactional即可

@Service
@Transactional
public class TaskService implements ITaskService {
}
也可在使用注解时定义事物的传播级别 隔离行为等。

@Transactional(propagation=Propagation.REQUIRED)

//注解详情
@Transactional(
            readOnly = false, // 读写事务
            timeout = -1, // 事务的超时时间不限制
            noRollbackFor = ArithmeticException.class, // 遇到数学异常不回滚
            isolation = Isolation.DEFAULT, // 事务的隔离级别,数据库的默认
            propagation = Propagation.REQUIRED // 事务的传播行为
    )


4、基于XML、aop的配置方式,目前项目中都是使用这种方式,有效的减少了代码量

   <!-- 定义事务通知 (事务的增强)-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
    <!-- 定义方法的过滤规则 -->
    <tx:attributes>
        <!-- 所有方法都使用事务 -->
        <!-- 
            propagation:事务传播行为
            isolation:事务隔离
            read-only:只读
            rollback-for:发生哪些异常回滚
            no-rollback-for:发生哪些异常不回滚 
            timeout:过期信息    
         -->
        <tx:method name="create*" propagation="REQUIRED"/>
        <tx:method name="add*" propagation="REQUIRED"/>
        <tx:method name="delete*" propagation="REQUIRED"/>
        <tx:method name="update*" propagation="REQUIRED"/>
        <tx:method name="change*" propagation="REQUIRED"/>
    </tx:attributes>
</tx:advice>

<!-- 定义AOP配置 配置切面 -->
<aop:config>
    <!-- 定义一个切入点 -->
    <aop:pointcut expression="execution (* ymy.com.service.impl.*.*(..))" id="services"/>
    <!-- 对切入点和事务的通知,进行适配 -->
    <aop:advisor advice-ref="txAdvice" pointcut-ref="services"/>
</aop:config>

作用域

spring作用域

#singleton
当一个bean的 作用域设置为singleton, 那么Spring IOC容器中只会存在一个共享的bean实例,并且所有对bean的请求,只要id与该bean定义相匹配,则只会返回bean的同一实例。换言之,当把 一个bean定义设置为singleton作用域时,Spring IOC容器只会创建该bean定义的唯一实例。这个单一实例会被存储到单例缓存(singleton cache)中,并且所有针对该bean的后续请求和引用都 将返回被缓存的对象实例,这里要注意的是singleton作用域和GOF设计模式中的单例是完全不同的,单例设计模式表示一个ClassLoader中 只有一个class存在,而这里的singleton则表示一个容器对应一个bean,也就是说当一个bean被标识为singleton时 候,spring的IOC容器中只会存在一个该bean。
单例 bean 存在线程问题,主要是因为当多个线程操作同一个对象的时候,对这个对象的非静态成员变量的写操作会存在线程安全问题。

#Prototype
prototype作用域部署的bean,每一次请求(将其注入到另一个bean中,或者以程序的方式调用容器的 getBean()方法)都会产生一个新的bean实例,相当与一个new的操作,对于prototype作用域的bean,有一点非常重要,那就是Spring不能对一个prototype bean的整个生命周期负责,容器在初始化、配置、装饰或者是装配完一个prototype实例后,将它交给客户端,随后就对该prototype实例不闻不问了。不管何种作用域,容器都会调用所有对象的初始化生命周期回调方法,而对prototype而言,任何配置好的析构生命周期回调方法都将不会被调用。 清除prototype作用域的对象并释放任何prototype bean所持有的昂贵资源,都是客户端代码的职责。(让Spring容器释放被singleton作用域bean占用资源的一种可行方式是,通过使用 bean的后置处理器,该处理器持有要被清除的bean的引用。)

#request
request表示该针对每一次HTTP请求都会产生一个新的bean,同时该bean仅在当前HTTP request内有效

#session
session作用域表示该针对每一次HTTP请求都会产生一个新的bean,同时该bean仅在当前HTTP session内有效

设计模式

Spring中涉及到的设计模式

工厂设计模式 : Spring使用工厂模式通过 BeanFactory、ApplicationContext 创建 bean 对象。
代理设计模式 : Spring AOP 功能的实现。
单例设计模式 : Spring 中的 Bean 默认都是单例的。
模板方法模式 : Spring 中 jdbcTemplate、hibernateTemplate 等以 Template 结尾的对数据库操作的类,它们就使用到了模板模式。
包装器设计模式 : 我们的项目需要连接多个数据库,而且不同的客户在每次访问中根据需要会去访问不同的数据库。这种模式让我们可以根据客户的需求能够动态切换不同的数据源。
观察者模式: Spring 事件驱动模型就是观察者模式很经典的一个应用。
适配器模式 :Spring AOP 的增强或通知(Advice)使用到了适配器模式、spring MVC 中也是用到了适配器模式适配Controller。


常用注解

常见问题

@Component 和 @Bean 的区别是什么?
作用对象不同: @Component 注解作用于类,而@Bean注解作用于方法。
@Component通常是通过类路径扫描来自动侦测以及自动装配到Spring容器中(我们可以使用 @ComponentScan 注解定义要扫描的路径从中找出标识了需要装配的类自动装配到 Spring 的 bean 容器中)。@Bean 注解通常是我们在标有该注解的方法中定义产生这个 bean,@Bean告诉了Spring这是某个类的示例,当我需要用它的时候还给我。
@Bean 注解比 Component 注解的自定义性更强,而且很多地方我们只能通过 @Bean 注解来注册bean。比如当我们引用第三方库中的类需要装配到 Spring容器时,则只能通过 @Bean来实现。

将一个类声明为Spring的 bean 的注解有哪些?
我们一般使用 @Autowired 注解自动装配 bean,要想把类标识成可用于 @Autowired注解自动装配的 bean 的类,采用以下注解可实现:
@Component :通用的注解,可标注任意类为 Spring 组件。如果一个Bean不知道属于拿个层,可以使用@Component 注解标注。
@Repository : 对应持久层即 Dao 层,主要用于数据库相关操作。
@Service : 对应服务层,主要涉及一些复杂的逻辑,需要用到 Dao层。
@Controller : 对应 Spring MVC 控制层,主要用户接受用户请求并调用 Service 层返回数据给前端页面。

@PostConstruct
@PostConstruct注解在某个用来初始化的方法上,注入时注入到另一个不是静态的变量里,然后在初始化方法里面将注入好的变量赋值给静态变量,通过这些操作就给静态变量赋值。

@RequestParam
放在参数前,表示只能接收参数a=b格式的数据,即Content-Type为application/x-www-form-urlencoded类型的内容。

@RequestBody
放在参数前,表示参数从request body中获取,而不是从地址栏获取,所以这肯定是接收一个POST请求的非a=b格式的数据,即Content-Type不为application/x-www-form-urlencoded类型的内容。

@RequestHeader
放在方法参数前,用来获取request header中的参数值。

@CookieValue
放在方法参数前,用来获取request header cookie中的参数值。

@Service
用于标注业务层组件,说白了就是加入你有一个用注解的方式把这个类注入到spring配置中

@Autowired
用来装配bean,都可以写在字段上,或者方法上。

@Resource
@Resource的作用相当于@Autowired
只不过@Autowired按byType自动注入,
而@Resource默认按 byName自动注入罢了。

@PostConstruct
用来标记是在项目启动的时候执行这个方法。用来修饰一个非静态的void()方法
也就是spring容器启动时就执行,多用于一些全局配置、数据字典之类的加载
被@PostConstruct修饰的方法会在服务器加载Servlet的时候运行,并且只会被服务器执行一次。PostConstruct在构造函数之后执行,init()方法之前执行。PreDestroy()方法在destroy()方法执行执行之后执

@PreDestroy
被@PreDestroy修饰的方法会在服务器卸载Servlet的时候运行,并且只会被服务器调用一次,类似于Servlet的destroy()方法。被@PreDestroy修饰的方法会在destroy()方法之后运行,在Servlet被彻底卸载之前

@Repository
用于标注数据访问组件,即DAO组件

@Component
泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注

@Scope
用来配置 spring bean 的作用域,它标识 bean 的作用域。

@Required
适用于bean属性setter方法,并表示受影响的bean属性必须在XML配置文件在配置时进行填充。否则,容器会抛出一个BeanInitializationException异常。

@Qualifier
当你创建多个具有相同类型的 bean 时,并且想要用一个属性只为它们其中的一个进行装配,在这种情况下,你可以使用 @Qualifier 注释和 @Autowired 注释通过指定哪一个真正的 bean 将会被装配来

@Configuration
声明当前类为配置类,相当于xml形式的Spring配置(类上)


Filter

过滤器实际上就是对web资源进行拦截,做一些处理后再交给下一个过滤器或servlet处理,通常都是用来拦截request进行处理的,也可以对返回的response进行拦截处理

应用场景
自动登录
统一设置编码格式
访问权限控制
敏感字符过滤等

















































































以上是关于Spring速查手册的主要内容,如果未能解决你的问题,请参考以下文章

Thread多线程速查手册

Grovvy速查手册

Kafka3.x核心知识速查手册-一快速上手篇

Kafka3.x核心知识速查手册-一快速上手篇

yii 速查手册

Linux速查手册