学习spring笔记,自用
什么是Spring
Spring框架是一个开放源代码的J2EE应用程序框架,由Rod Johnson发起,是针对bean的生命周期进行管理的轻量级容器(lightweight container)。 Spring解决了开发者在J2EE开发中遇到的许多常见的问题,提供了功能强大IOC、AOP及Web MVC等功能。Spring可以单独应用于构筑应用程序,也可以和Struts、Webwork、Tapestry等众多Web框架组合使用,并且可以与 Swing等桌面应用程序AP组合。因此, Spring不仅仅能应用于JEE应用程序之中,也可以应用于桌面应用程序以及小应用程序之中。
Spring框架主要由七部分组成,分别是 Spring Core、 Spring AOP、 Spring ORM、 Spring DAO、Spring Context、 Spring Web和 Spring Web MVC。
Spring是全面的和模块化的。Spring有分层的体系结构,这意味着你能选择使用它孤立的任何部分,它的架构仍然是内在稳定的。
它的设计从底部帮助你编写易于测试的代码。Spring是用于测试驱动工程的理想的framework。
IOC控制反转——由容器控制程序之间的(依赖)关系
-
在Spring当中定义和配置JavaBean:注解方式
-
注解:使用前需要在xml文件中配置自动扫描—— <context:component-scan base-package="com.mgy"></context:component-scan>
-
@AutoWired 自动装配,默认按照类型匹配
-
如果容器中没有一个和标注变量类型匹配的Bean,Spring容器启动时将报NoSuchBeanDefinitionException的异常。如果希望Spring即使找不到匹配的Bean完成注入也不用抛出异常,那么可以使用@Autowired(required=false)进行标注
-
如果容器中有一个以上匹配的Bean时,则可以通过@Qualifier注解限定Bean的名称
-
-
@Componet(默认单例模式)组件
-
@Controller 标注在Controller层
-
@Service 标注在Service层
-
@Pepository 标注在Dao层
-
@ComponentScan 扫描组件
-
-
@Resource :功能等同于 @Autowired + @Qualifier,等同配置文件标签 <property name="" ref="" >;只能注入方法和属性,不支持注入构造方法
-
@Configuration 作为配置注入Spring
-
@PostConstruct:初始化方法
-
@PreDestroy:销毁方法
-
-
spring注入bean的四种方法
-
通过注解注入的一般形式:@Bean
-
@Bean是一个方法级别上的注解,主要用在@Configuration注解的类里,也可以用在@Component注解的类里
-
-
通过构造方法注入Bean:执行有参构造函数时自动装配
-
通过set方法注入Bean 显式调用setter方法时自动装配
-
通过属性去注入Bean 直接在属性上自动装配
-
-
-
在Spring当中定义和配置JavaBean:xml配置方式
-
bean的声明周期有四个阶段
-
实例化:通过构造器或工厂方法创建 Bean 实例
-
id:容器中查找Bean的id(唯一且不能以/开头)
-
class:bean的完整类名
-
name:在容器中查找bean的名字(唯一、允许以/开头,允许多个值且以逗号或空格隔开)
-
scope:作用域 singleton、prototype 等
-
abstract:将bean定义成抽象bean,不能实例化
-
parent:父bean,必须存在继承关系
-
init-method:指定bean对象的初始化方法
-
-
属性赋值:
-
简单属性赋值:<property name="name"> <value>zs</value> </property>
-
构造器赋值:<constructor-arg index="0"><value>zzz</value></constructor-arg>
-
值为javabean:<bean id="ss" class="p1.Student"><property name="helloworld"><ref bean="helloworlds"></property>
-
值为list或数组:<property name="arr/list"><list><value>aa</value><value>bb</value><value>cc</value><value>dd</value></list></property>
-
值为map:<property name="map"><map><entry><key><value>zs</value></key><value>张三</value></entry><entry><key><value>ls</value></key><value>李四</value></entry></map></property>
-
值为properties:<property name="properties"><props><prop key="a2">222</prop></props></property>
-
-
初始化:init-method 参数配置初始化方法
-
销毁:destroy-method 参数配置销毁方法
-
-
bean的作用域:使用scope属性配置
-
singleton单例模式(多线程不安全)
-
prototype原型模式
-
request单次请求模式:<bean id="loginAction" class="com.cnblogs.Login" scope="request"/>
-
session会话模式
-
global Session全局会话模式:在一个全局的 Http Session 中,容器会返回该 Bean 的同一个实例,仅在使用 portlet context 时有效。
-
-
<!--xml方式配置bean-->
<!--属性注入-->
<bean class="com.baobaotao.anno.LogonService">
<property name="logDao" ref="logDao"></property>
<property name="userDao" ref="userDao"></property>
<!--构造方法注入-->
<bean class="com.baobaotao.anno.LogonService">
<constructor-arg ref="logDao"></constructor-arg>
<constructor-arg ref="userDao"></constructor-arg>
</bean>
<!--静态工厂方法注入-->
<bean id="car6" class="com.baobaotao.ditype.CarFactory"
factory-method="createCar"></bean>
AOP面向切面——分离应用的业务逻辑与系统级服务
-
AOP主要应用场景
-
Authentication 权限
-
Caching 缓存
-
Context passing 内容传递
-
Error handling 错误处理
-
Lazy loading 懒加载
-
Debugging 调试
-
logging, tracing, profiling and monitoring 记录跟踪 优化 校准
-
Performance optimization 性能优化
-
Persistence 持久化
-
Resource pooling 资源池
-
Synchronization 同步
-
Transactions 事务
-
-
AOP 领域中的特性术语:
-
通知(Advice): AOP 框架中的增强处理。通知描述了切面何时执行以及如何执行增强处理。
-
连接点(join point): 连接点表示应用执行过程中能够插入切面的一个点,这个点可以是方法的调用、异常的抛出。在 Spring AOP 中,连接点总是方法的调用。
-
切点(PointCut): 可以插入增强处理的连接点。
-
切面(Aspect): 切面是通知和切点的结合。
-
引入(Introduction):引入允许我们向现有的类添加新的方法或者属性。
-
织入(Weaving): 将增强处理添加到目标对象中,并创建一个被增强的对象,这个过程就是织入。
-
-
Spring AOP实现
-
注解实现
-
通过注解声明切点指示器
-
arg():限制连接点匹配参数为执行味蕾的执行方法
-
@arg():限制连接点匹配参数由指定注解标注的执行方法
-
*execution():用于匹配是连接点的执行方法
-
this():限制连接点匹配AOP代理的Bean应用为指定类型的类
-
target():限制链接点匹配目标对象为指定类型的类
-
@target():限制连接点匹配特点的执行对象,这些对象相应的类要具备执行类型的注释
-
within():限制连接点匹配指定的类型
-
@within():限制连接点匹配指定注解所标注的类型(当使用Spring AOP时, )
-
@annotation:限制匹配带有指定注解连接点
-
bean():指定使用切面的bean
-
-
通过注解声明5种通知类型
-
@Before 通知方法会在目标方法调用之前执行
-
@After 通知方法会在目标方法返回或异常后调用
-
@AfterReturning 通知方法会在目标方法返回后调用
-
@AfterThrowing 通知方法会在目标方法抛出异常后调用
-
@Around 通知方法会将目标方法封装起来
-
-
通过注解声明切点表达式: @Pointcut 声明切点表达式
-
-
@Pointcut("execution(* com.sharpcj.aopdemo.test1.IBuy.buy(..))")
public void point(){}
-
-
通过注解处理通知中的参数:args(参数)
-
@Pointcut("execution(String com.sharpcj.aopdemo.test1.IBuy.buy(double)) && args(price) && bean(girl)")
public void gif(double price) {}
-
通过注解配置织入的方式
-
@EnableAspectJAutoProxy( proxyTargetClass=true):扫描并解析aop注解的入口。
-
proxyTargetClass 参数值默认为false;
-
true
-
目标对象实现了接口——使用CGLIB代理机制
-
目标对象没有接口(只有实现类)——使用CGLIB代理机制
-
-
false
-
目标对象实现了接口——使用JDK动态代理机制(代理所有实现了的接口)
-
目标对象没有接口(只有实现类)——使用CGLIB代理机制
-
-
-
-
通过XML配置文件声明切面
-
AOP常用元素
-
<aop:advisor>:定义AOP通知器
-
<aop:after>:定义一个后置通知(不管目标方法是否执行成功)
-
<aop:afterreturning>:定义AOP返回通知
-
<aop:afterthrowing>:定义AOP异常通知
-
<aop:around>:定义环绕通知
-
<aop:aspect>:定义一个切面
-
<aop:aspectj-autoproxy>:启动@AspectJ注解驱动的切面
-
<aop:before>:定义一个AOP前置通知
-
<aop:config>:顶层AOP配置元素
-
<aop:decare-parents>:以透明方式为被通知的对象引入额外的接口
-
<aop:pointcut>:定义一个切点
-
<aop:aspectj-autoproxy> :自动代理AspectJ注解的通知类
-
-
XML配置文件中切点指示器:与注解类似,&&需要换成and,其他同理
-
XML文件配置声明切点: <aop:pointcut id="apoint" expression="execution(* com.sharpcj.aopdemo.test2.IBuy.buy(..))"/>
-
XML文件配置为通知传递参数:与注解一致
-
XML文件配置织入的方式
-
CGlib代理:<aop:config proxy-target-class="true"> </aop:config>
-
利用ASM开源包,对代理对象类的class文件加载进来,通过修改其字节码生成类来处理。
-
如果目标实现了接口,可以强制使用CGLIB实现AOP
-
如果目标对象没有实现了接口,必须采用CGLIB库,spring会自动在JDK动态代理和CGLIB之间转换。
-
如何强制使用CGLIB实现AOP
-
添加CGLIB库:aspectjrt-xxx.jar、aspectjweaver-xxx.jar、cglib-nodep-xxx.jar
-
在spring配置文件中加入<aop:aspectj-autoproxy proxy-target-class="true"/>
-
-
CGLIB是针对类实现代理的,主要是对指定的类生成一个子类,覆盖其中的方法,并覆盖其中方法实现增强,但是因为采用的是继承,所以该类或方法最好不要声明成final,因为final类或方法,是无法继承的。
-
-
JDK代理方式:<aop:config proxy-target-class="false"> </aop:config>
-
利用拦截器(拦截器必须实现InvocationHandler)加上发射机制生成一个实现代理接口的匿名类;在调用具体方法前调用InvokeHander来处理
-
如果目标实现了接口,默认情况下会采用JDK的动态代理来实现AOP
-
JDK动态代理只能对实现了接口的类生成代理,而不能针对类。
-
-
-
框架——可以进行事务管理、安全、日志、持久化框架集成
-
事务管理 是对于一系列数据库操作进行管理。
-
一个事务包含一个或多个SQL语句,是逻辑管理的工作单元(原子单元)。
-
一个事务开始于第一次执行的SQL语句,结束于Commit或Rollback或DDL(data definition language ,数据定义语言)语句
-
事务处理(TRANSACTION)是由一个或多个SQL语句序列结合在一起所形成的一个逻辑处理单元。
-
在Spring项目中,我们可以通过四种方式来实现事务管理
-
编程式事务管理
-
基于 TransactionProxyFactoryBean的声明式事务管理 : <tx:annotation-driven transaction-manager="transactionManager"/>
-
基于 @Transactional 的声明式事务管理 : @Transactional(transactionManager = "transactionManager", rollbackFor = Exception.class)
-
基于Aspectj AOP配置事务
-
-
<!-- 事务管理器 -->
<bean id="tracnsactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<tx:advice id="txAdvice" transaction-manager="myTracnsactionManager">
<tx:attributes>
<!-- 为连接点指定事务属性 -->
<tx:method name="add*" isolation="DEFAULT" propagation="REQUIRED"/>
<tx:method name="stockChange" isolation="DEFAULT" propagation="REQUIRED" rollback-for="StockException"/>
</tx:attributes> </tx:advice> <aop:config>
<!-- 切入点配置 -->
<aop:pointcut expression="execution(* *..service.*.*(..))" id="point"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="point"/>
</aop:config>
-
事务传播机制
-
REQUIRED:如果有事务则加入事务,如果没有事务,则创建一个新的(默认值);
-
NOT_SUPPORTED:Spring 不为当前方法开启事务,相当于没有事务;
-
REQUIRES_NEW:不管是否存在事务,都创建一个新的事务,原来的方法挂起,新的方法执行完毕后,继续执行老的事务;
-
MANDATORY:必须在一个已有的事务中执行,否则报错;
-
NEVER:必须在一个没有的事务中执行,否则报错;
-
SUPPORTS:如果其他 bean 调用这个方法时,其他 bean 声明了事务,则就用这个事务,如果没有声明事务,那就不用事务; SUPPORTS类型的事务传播机制,是否使用事务取决于调用方法是否有事务,如果有则直接用,如果没有则不使用事务。
-
NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与 REQUIRED 类似的操作;
-
注意:在 A 方法内,调用 B 方法时,存在以下规则:
1. REQUIRED
当两个方法的传播机制都是 REQUIRED 时,如果一旦发生回滚,两个方法都会回滚;
2. REQUIRES_NEW
当 A 方法传播机制为 REQUIRES_NEW ,会开启一个新的事务,并单独提交方法,所以 B 方法的回滚并不影响 A 方法事务提交;
3. NESTED
当 A 方法为 REQUIRED,B 方法为 NESTED 时,A 方法开启一个嵌套事务;
当 A 方法回滚时,B 方法也会回滚;反之,如果 B 方法回滚,则并不影响 A 方法的提交。
-
事务隔离级别
-
ISOLATION_DEFAULT:使用后端数据库默认的隔离界别,MySQL默认采用的REPEATABLE_READ 隔离级别,Oracle 默认采用的 READ_COMMITTED 隔离级别;
-
ISOLATION_READ_UNCOMMITTED:最低的隔离级别,允许读取,允许读取尚未提交的的数据变更,可能会导致脏读、幻读或不可重复读;
-
ISOLATION_READ_COMMITTED:允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生;
-
ISOLATION_REPEATABLE_READ:对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生;
-
ISOLATION_SERIALIZABLE:最高的隔离级别,完全服从 ACID 的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就说,该级别可以阻止脏读、不可重复读以及幻读。但是这将严重影响程序的性能。通常情况下也不会用到该级别。
-
-
持久化框架集成
-
Hibernate框架集成
-
Mybatis框架集成
-
-
安全
-
日志
容器——Ioc容器负责容纳此前所描述的bean,并对bean进行管理。
-
IOC 容器主要由 BeanFactory 和 ApplicationContext 组成。BeanFactory 是 Spring 框架的基础设施,面向 Spring 本身;ApplicationContext 面向使用 Spring 框架的开发者,几乎所有的应用场合我们都直接使用 ApplicationContext 而非底层的 BeanFactory。
-
BeanFactory 是 Spring 框架的基础设施,面向 Spring 本身,BeanFactory 主要有以下组件:
-
BeanDefinitionRegistry:注册表,提供了向容器手工注册 BeanDefinition 对象的方法。Spring 配置文件中每一个节点元素在 Spring 容器里都通过一个 BeanDefinition 对象表示,它描述了 Bean 的配置信息;
-
BeanFactory:顶层接口。它最主要的方法就是 getBean(String beanName),该方法从容器中返回特定名称的 Bean;
-
ListableBeanFactory:该接口定义了访问容器中 Bean 基本信息的若干方法,如查看 Bean 的个数、获取某一类型 Bean 的配置名、查看容器中是否包括某一 Bean 等方法;
-
HierarchicalBeanFactory:父子级联 IOC 容器的接口,子容器可以通过接口方法访问父容器; 通过HierarchicalBeanFactory 接口, Spring 的 IOC 容器可以建立父子层级关联的容器体系,子容器可以访问父容器中的 Bean,但父容器不能访问子容器的 Bean。Spring 使用父子容器实现了很多功能,比如在 Spring MVC 中,展现层 Bean 位于一个子容器中,而业务层和持久层的 Bean 位于父容器中。这样,展现层 Bean 就可以引用业务层和持久层的 Bean,而业务层和持久层的 Bean 则看不到展现层的 Bean;
-
ConfigurableBeanFactory:定义了设置类装载器、属性编辑器、容器初始化后置处理器等方法,增强了 IOC 容器的可定制性;
-
AutowireCapableBeanFactory:定义了将容器中的 Bean 按某种规则(如按名字匹配、按类型匹配等)进行自动装配的方法;
-
SingletonBeanRegistry:定义了允许在运行期间向容器注册单实例 Bean 的方法;对于单实例( singleton)的 Bean 来说,BeanFactory 会缓存 Bean 实例,所以第二次使用 getBean() 获取 Bean 时将直接从IOC 容器的缓存中获取 Bean 实例。Spring 在 DefaultSingletonBeanRegistry 类中提供了一个用于缓存单实例 Bean 的缓存器,它是一个用 HashMap 实现的缓存器,单实例的 Bean 以 beanName 为键保存在这个 HashMap 中。
-
依赖日志框架:在初始化 BeanFactory 时,必须为其提供一种日志框架,比如使用 Log4J, 即在类路径下提供 Log4J 配置文件,这样启动 Spring 容器才不会报错。
-
-
*ApplicationContext 面向开发应用
-
ApplicationContext 由 BeanFactory 派 生 而 来 , 提 供 了 更 多 面 向 实 际 应 用 的 功 能 。ApplicationContext 继承了 HierarchicalBeanFactory 和 ListableBeanFactory 接口,在此基础上,还通过多个其他的接口扩展了 BeanFactory 的功能:
-
ClassPathXmlApplicationContext:默认从类路径加载配置文件
-
FileSystemXmlApplicationContext:默认从文件系统中装载配置文件;
-
ApplicationEventPublisher:让容器拥有发布应用上下文事件的功能,包括容器启动事件、关闭事件等
-
MessageSource:为应用提供 i18n 国际化消息访问的功能;
-
ResourcePatternResolver: 所有 ApplicationContext 实现类都实现了类似于 PathMatchingResourcePatternResolver 的功能,可以通过带前缀的 Ant 风格的资源文件路径装载 Spring 的配置文件;
-
LifeCycle:该接口是 Spring 2.0 加入的,该接口提供了 start()和 stop()两个方法,主要用于控制异步处理过程。在具体使用时,该接口同时被 ApplicationContext 实现及具体Bean 实现, ApplicationContext 会将 start/stop 的信息传递给容器中所有实现了该接口的 Bean,以达到管理和控制 JMX、任务调度等目的;
-
ConfigurableApplicationContext:扩展于 ApplicationContext,它新增加了两个主要的方法: refresh()和 close(),让 ApplicationContext 具有启动、刷新和关闭应用上下文的能力。在应用上下文关闭的情况下调用 refresh()即可启动应用上下文,在已经启动的状态下,调用 refresh()则清除缓存并重新装载配置信息,而调用 close()则可关闭应用上下文。
-
-
WebApplicationContext
-
WebApplicationContext 是专门为 Web 应用准备的,它允许从相对于 Web 根目录的路径中装载配置文件完成初始化工作。从 WebApplicationContext 中可以获得ServletContext 的引用,整个 Web 应用上下文对象将作为属性放置到 ServletContext 中,以便 Web 应用环境可以访问 Spring 应用上下文。
-