Spring 学习笔记

Spring

这里写图片描述

IOC&DI概述

IOC是一种思想,即控制反转,

将控制的权限给了IOC容器,对象被动的依赖参数的注入。

不同于以往主程序是老大,主程序创建对象调用方法获取参数,而是将对象的创建,参数的获取和修改放在了xml配置文件中。利用IOC容器,调用需要的bean创建对象,同时注入需要的value值。

自动装配bean

自动注入需要的bean

xml中<bean>标签里带有autowire属性

参数:

byName:根据id,装配指定的已有的bean,要求bean的id与类中setter方法的name(setName的name)一致,(与参数无关,若没有对应id的,则装配null)

byType:将对应类型的bean装配(类型指class),要求IOC容器有且仅有一个符合类型(class)的bean,否则抛异常

Bean的生命周期

这里写图片描述

Bean中带有初始化和销毁方法的引用

init-method

destroy-method

具体方法需在注入类中实现

实现接口BeanPostProcessor

这里写图片描述


<!-- 配置bean的后置处理器,不需要配置id,IOC容器自动识别是一个BeanPostProcessor -->

<bean class="com.mar.spring.beans.MyBeanPostProcessor">

方法中的参数

bean:bean本身

beanName:IOC容器配置的bean的名字

返回值:是实际上返回给用户的那个bean

注意:可以在以上两个方法中修改返回的bean类,甚至是另一个bean类

Object postProcessBeforeInitialization(Object bean, String beanName)

方法在init-method之前实现

Object postProcessAfterInitialization(Object bean, String beanName)

方法在init-method之后被实现

工厂bean的配置方法

这里写图片描述

静态工厂方法

创建静态工厂方法,静态代码块中配置<String,Bean>键值对,

创建静态getter方法return需要的bean对象.

配置xml中bean实例,添加factory-method确认getter方法,使用构造入参获取value值

class:指向静态工厂方法的全类名

factory-method:指向静态工厂方法的名字

constructor-arg:配置传入参数

实例化工厂方法

创建实例工厂方法,构造方法中配置<String,Bean>键值对,

创建getter方法return需要的bean对象.(非静态)

配置xml中工厂实例和bean实例,


<!-- 配置工厂的实例 -->

<bean id="carFactory" class="com.mar.factory.InstanceCarFactory">

</bean>

<!-- 通过实例工厂方法来配置bean -->

<bean id="car2" factory-bean="carFactory" factory-method="getCar">

<constructor-arg value="audi"></constructor-arg>

</bean>

通过fanctory-bean和factory-method确认工厂bean和工厂方法,<constructor-arg>获取参数

通过FactoryBean实例创建

创建类,继承FactoryBean接口,重写实现类方法。

getObject():返回bean的对象

getObjectType():返回bean的类型

isSingleton():返回对象是否是单例

xml配置:

<bean id="name" class="com...FactoryBean" ></bean>

class:指向FactoryBean的全类名

property:配置FactoryBean的属性

通过注解配置bean

xml中配置<context:component-scan base-package=""></context:component-scan>

自动扫描包

@Component

@Respository dao层

@Service service层

@Controller web层

这两个经常一起用,自动装配,同时指定装配的bean

@Autowired

@Qualifier(“”)

同时可配置子节点

context:exclude-filter

context:include-filter

指定包含和不包含的包

例:

<context:exclude-filter type="annotation"

expression="org.springframework.stereotype.Repositorya " />

type指定过滤类型,

annotation:注解

assignable:全类名

aspectj:AspectJ语法

regex:Regelar Expression

use-default-filter:开启是否使用自定义过滤器

泛型依赖注入
bean的作用域

xml配置bean - scope作用域

AOP

这里写图片描述

Spring AOP

(使用了AspectJ)

1、相关jar包

(AspectJ相关)

com.springsource.org.aopalliance-1.0.0.jar

com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar

spring-aop-4.0.0.RELEASE.jar

spring-aspects-4.0.0.RELEASE.jar

(Spring相关)

com.springsource.net.sf.cglib-2.2.0.jar

commons-logging-1.1.1.jar

spring-beans-4.0.0.RELEASE.jar

spring-context-4.0.0.RELEASE.jar

spring-core-4.0.0.RELEASE.jar

spring-expression-4.0.0.RELEASE.jar

2、在配置文件中加入aop的命名空间

3、基于注解的方式

1、在配置文件中加入如下配置:

<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

2、把横切关注点的代码抽象到切面的类中

1、切面首先是一个IOC中的bean,即加入@Component注解

2、切面还需要加入@AspectJ注解

3、在类中声明各种通知

@Before:前置通知

@After:后置通知

@AfterThrowing:异常通知,在方法抛出异常之后

@AfterReturning:返回通知,在方法返回结果之后

@Around:环绕通知,围绕着方法执行

4、可以在通知方法中声明一个类型为 JoinPoint 的参数,然后就能访问连接细节,如,方法名称和参数值


public void afterMethod(JoinPoint joinPoint){

String methodName = joinPoint.getSignature().getName();

Object[] args = joinPoint.getArgs();

System.out.println("the method "+ methodName +" ends..."+ Arrays.asList(args));

}
AOP底层

动态代理

InvocationHandler重写方法

@Override

public Object invoke(Object proxy,Method method,Object[] args){

String methodName = method.getname();

Object result = null;

try{

//前置通知

result = method.invoke(target,args);

//返回通知,可以访问到返回值

}catch (Exception e){

e.printStackTrace();

//异常通知,可以访问到方法

}

//后置通知,因为方法可能异常,所以访问不到返回值

return result;

}
基于AspectJ注解方式

这里写图片描述

前置通知

@Before(“execution(public com.mar.*(int ,int))”)

后置通知

@After(“execution(public com.mar.*(int ,int))”)

后置通知是在连接点完成之后执行的,即连接点返回结果或者抛出异常的时候,下面的后置通知记录了方法的终结

一个切面可以包括一个或者多个通知(Advice)

后置通知中不能访问目标方法的执行结果,

只有返回通知(AfterRunning)能访问

返回通知

@AfterReturning

异常通知
/*

* 在目标方法出现异常时会执行的代码

* 可以访问到异常对象;且可以指定在出现特定异常时再执行通知代码

*/

@AfterThrowing(value="execution(public int com.mar.spring.aop.impl.ArithmeticCalculator.*(..))",

throwing="ex")

public void afterThrowing(JoinPoint joinPoint ,Exception ex){

String methodName = joinPoint.getSignature().getName();

System.out.println("the method "+ methodName +" occurs excetion "+ ex);

}
环绕通知
@Around

/*

* 环绕通知需要携带ProceedingJoinPoint类型的参数

* 环绕通知类似于动态代理的全过程:ProceedingJoinPoint可以决定是否执行目标方法

* 且必须要有返回值,返回值即为目标方法的返回值

*/

@Around("execution(public int com.mar.spring.aop.impl.ArithmeticCalculator.*(..))")

public Object aroundMethod(ProceedingJoinPoint pdj){

Object result = null;

String methodName = pdj.getSignature().getName();

//执行目标方法

try {

//前置通知

System.out.println("aroundMethod.."+ methodName);

//执行目标方法

result = pdj.proceed();

//返回通知

System.out.println("ends..."+result);

} catch (Throwable e) {

//异常通知

e.printStackTrace();

}

//后置通知

return result;

}
优先级

@Order(1)

使用order注解标记优先级,值越小,优先级越高

注解Advice书写重复解决方案

@Pointcut

/*

  • 定义一个方法,用于声明切入点表达式。一般地,该方法中不需要添入其它代码

  • 用途:解决注解中Advice的重复书写

  • 其他java类中,可以使用(包名)类名加方法名使用

  • 例:LoggingAspect.declareJointPointExpression()

*/

@Pointcut(“execution(public int com.mar.spring.aop.impl.ArithmeticCalculator.*(..))”)

public void declareJointPointExpression(){}

@Before(value=”declareJointPointExpression()”)

public void beforeMethod(JoinPoint joinPoint){

String methodName = joinPoint.getSignature().getName();

Object[] args = joinPoint.getArgs();

System.out.println(“the method “+ methodName +” begins…”+ Arrays.asList(args));

}

//***************************************

VlidationAspect.java

@Aspect

@Component

@Order(1)//指定优先级 ,值越小,优先级越高

public class VlidationAspect {

@Before(“LoggingAspect.declareJointPointExpression()”)

public void validateArgs(JoinPoint joinPoint){

System.out.println(“validate:” + Arrays.asList(joinPoint.getArgs()));

}

}

基于xml配置方式

//详情见spring-3项目com.mar.spring.aop.xml下

<!-- 配置bean -->

<bean id="arithmeticCalculator"

class="com.mar.spring.aop.xml.ArithmeticCalculatorImpl"></bean>

<!-- 配置切面bean -->

<bean id="loggingAspect"

class="com.mar.spring.aop.xml.LoggingAspect"></bean>

<bean id="vlidationAspect"

class="com.mar.spring.aop.xml.VlidationAspect"></bean>

<!-- 配置AOP -->

<aop:config>

<!-- 配置切点表达式 -->

<aop:pointcut expression="execution(* com.mar.spring.aop.xml.ArithmeticCalculator.*(int , int ))"

id="pointcut"/>

<!-- 配置切面aspect及通知advice -->

<aop:aspect ref="loggingAspect" order="2">

<aop:before method="beforeMethod" pointcut-ref="pointcut"/>

<aop:after method="afterMethod" pointcut-ref="pointcut"/>

<aop:after-throwing method="afterThrowing" pointcut-ref="pointcut" throwing="ex"/>

<aop:after-returning method="afterReturning" pointcut-ref="pointcut" returning="result"/>

</aop:aspect>

</aop:config>

spring JDBC框架

这里写图片描述

jdbcTemplate
jdbcDaoSupport
具名参数

事务

这里写图片描述

事务管理是企业级应用程序开发中必不可少的技术,用来确保数据的完整性和一致性

事务就是一系列的动作,它们被当作一个独立的工作单元。这些动作要么完成,要么全部不起作用

事务的四个关键属性ACID

  • 原子性(atomicity):事务是一个原子操作,由一系列动作组成,事务的原子性确保动作要么全部完成,要么全部不起作用

  • 一致性(consistency):一旦所有失误动作完成,事务就要被提交。数据和资源就处于一种满足业务规则的一致性状态中。

  • 隔离性(isolation):可能有许多事务会同时处理相同的数据,因此每个事务都应该与其他事务隔离开来,防止数据损坏。

  • 持久性(durability):一旦事务完成,无论发生什么系统错误,它的结果都不应该受到影响,通常情况下,事务的结果被写到持久化存储器中。

声明式事务

这里写图片描述

基于注解的方式

这里写图片描述

<!-- 配置事务管理器 -->

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

<property name="dataSource" ref="dataSource"></property>

</bean>

<!-- 启用事务注解 -->

<tx:annotation-driven transaction-manager="transactionManager" />
@Transactional事务注解

带有该注解的方法,一但出异常,抛出异常后,自动回滚

1、事务的传播属性

  • 当事务方法的另一个事务方法调用时,必须指定事务应该如何传播,例如:方法可能继续在现有事务中运行,也可能开启了一个新事务,并在自己的事务中运行

  • 事务的传播行为可以有传播属性指定,Spring定义了7种类传播行为

传播属性(常用)

REQUIRED(默认) 如果有事务在运行,当前的方法就在这个事务内运行,(回滚到上一个事务的起点)否则,就起用一个新的事务,并在自己的事务内运行

REQUIRED_NEW 当前的方法必须启动新事物,并在它自己的事务内运行,如果有事务正在运行,应该将它挂起(回滚到自己事务的起点)

使用propagation指定事务的传播行为

@Transactional(propagation=Propagation.REQUIRED)

2、事务的隔离级别

最常用的取值READ_COMMITTED

@Transactional(isolation=Isolation.READ_COMMITTED)

3、事务默认情况下对所有的运行时期异常回滚,

也可以通过对应的属性进行设置

@Transactional(noRollbackFor={UserAccountException.class})

4、事务的只读,指定事务是否为只读,表示这个事务只读取数据不更新数据,这样可以帮助数据库优化事务

@Transactional(readOnly=true)

5、事务的过期

指定强制回滚之前,事务可以占用的时间,防止一个事务对运行占用时间过长,单位/秒

@Transactional(timeout=1)

基于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>

<tx:method name="*" />

</tx:attributes>

</tx:advice>

<!-- 3、配置事务切入点,以及把事务切入点和事务属性关联起来 -->

<aop:config>

<aop:pointcut expression="execution(* com.mar.spring.tx.xml.BookShopService.*(..))" id="txPoinCut" />

<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut" />

</aop:config>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值