Spring基础应用

176 阅读8分钟

目录

一、Spring基础

1.IoC和DI的思想

2.getBean方法

3.Spring基本配置

二、Ioc容器

1.Ioc容器

2.DI依赖注入

3.DI注解

4.IoC注解

三、AOP面向切面

1.代理模式

2.动态代理的实现

3.AOP面向切面编程

4.Spring的AOP开发

四、DAO持久化

1.事务

2.事务的配置

一、Spring基础

1.IoC和DI的思想

1、没有IoC(控制反转)和DI(依赖注入),调用者需要使用某个对象,其自身就得负责该对象及该对象所依赖对象的创建和组装;

2、通过IoC和DI的思想,就是将原本在程序中手动创建对象的控制权,交由Spring框架来管理;对象的管理和依赖注入不需要自己去实现;

2.getBean方法

1、按照bean的名字查找:world=(HelloWorld) factory. getBean ("helloWorld") ;

2、按照bean的类型查找:world = factory.getBean (HelloWorld.class) ;

3、按照名字和类型查找: (推荐):world=factory.gecBean ("helloWorld", HelloWorld.class) ;

3.Spring基本配置

1、Bean中的id和name属性:spring3.1之后相同,可以起多个别名使用逗号或者空格分开;

2、xml文件分割:使用<import resource = "classpath:cn/wolfcode/day1/02_hello/hello.xml"/>进行组合;

二、Ioc容器

1.Ioc容器

1、BeanFactory: Spring最底层的接口,只提供了的IoC功能,负责创建、组装、管理bean;使用了懒加载,getBean时候才会初始化Bean;

2、ApplicationContext接口:继承了BeanFactory,除此之外还提供AOP集成、国际化处理、事件传播、统一资源加载等功能;在初始化容器的时候就会初始化Bean;

1.1.bean实例化方式(需要使用@Autowired注解来声明)

1、构造器实例化(无参数构造器);

2、静态工厂方法实例化:解决系统遗留问题;

3、实例工厂方法实例化:解决系统遗留问题;

4、实现FactoryBean接口实例化;

ps:都需要在xml文件里进行设置;

1.2.bean作用域

1、singlecon:单例,在Spcing IoC容器中仅存在一个bean实例(默认的scope);

2、prototype:多例,每次从容器中调用Bean时,都返回一个新的实例,即每次调用getBean()时,相当于执行new XxxBean(): 会在容器启时创建对象;

3、request:用于web开发,将Bean加入request范围,request.setAttribute("xxx"),在同一个reques获得同一个Bean;

4、session:用于web开发, 将Bean放入Session范围,在同一个Session中获得同一个Bean;

5、globalSession: 一般用于porlet应用环境,分布式系统存在全局session概念(单点登录),如果不是porlet环境,globalSession等同于Session;

1.3.bean的创建和销毁

1、init-method: bean生命周期初始化方法,bean创建后会进行调用;

2、destroy-method:容器被销毁的时候,如果bean被容器管理,bean销毁之前调用该方法;

ps:单例bean会执行销毁方法,多例bean是不会销毁容器的,因为bean可能有多个容器可能会再次创建(因为bean要往容器注册),造成资源浪费;

2.DI依赖注入

1、指Spring创建对象的过程中,将对象依赖属性(常量,对象,集合)通过设置值给该对象。

2、可以通过调用对象的setter方法.

3、可以在创建对象的时候(调用构造器),同时设置对象的属性值.

3.DI注解

1、使用@Autowired注解,在配置xml文件进行DI依赖注入注解配置<context:annotation- config />;是Spring规范提供的;

2、Autowired注解寻找bean的方式:

3、首先按照依赖对象的类型找,如果找到,就是用setter或者字段直接注入;

4、如果在Spring上下文中找到多个匹配的类型,再按照名字去找,如果没有匹配报错;

5、使用@Resource注解(类似于Autowired注解),是JavaEE规范提供的;

4.IoC注解

1、使用@Component ("myDataSource") 组件如果不写value属性值,此时bean的id默认是类的首字母小写 ;

2、等价于<bean id="myDataSource" class="cn.wolfcode.ioc.MyDataSource"/ >,但是需要在xml进行IoC容器注解配置:<context:component-scan base-package="com.miaosha.*"/>

3、类似@Service,@Controller,@Repository注解,全部放在类上;@Component(泛指组件)

4、配置bean作用域需要加入@Scope ("prototype");

5、配置init和destroy方法需要在对应方法,加上注解@PostConstruct;@PreDestroy;

三、AOP面向切面

1.代理模式

1、客户端调用实际类,要对该调用进行增强可以通过代理类对调用进行拦截增强,代理类组合了实际类,让调用面向代理类而不是实际类;

2、客户端使用的都是代理对象而不是实际对象,通过代理类在客户端和实际对象之间起到中介的作用;

1.1静态代理

在程序运行前就已经存在代理类的字节码文件,代理对象和真实对象的关系在运行前就确定了。

1.2动态代理

在程序运行期间由JVM通过反射等机制动态的生成,代理对象和真实对象的关系是在程序运行时期才确定的

2.动态代理的实现

1、针对实际对象target实现了接口:使用JDK动态代理;(Advice增强代理类,实现reflect里的InvocationHandler接口,包含target要增强对象(实际对象))

原理:生成的代理类实现了实际对象的接口;

2、针对实际对象target没有接口无法实现:使用CGLIB或Javassist组件;(Advice增强代理类,实现cglib里的InvocationHandler接口,包含target要增强对象(实际对象))

原理:生成的代理类继承了实际对象;

3.AOP面向切面编程

1、OOP面向对象的组合和继承可以消除重复,但是代码耦合度大;

2、引出了AOP切面(横切关注点)来对原有对象功能的增强,可以达到解耦合;实现原理(动态代理);

3.1专业术语:

1、JoinPoint:需要被增强的方法,代表哪一个方法需要被增强;

2、Pointcut:切入点,哪些方法需要被增强,是JoinPoint的一个集合;

3、Advice:增强(通知),当拦截到JoinPoint后,在方法执行的某一时机(前置/后置/异常/最终/环绕增强)进行操作,进行增强;

4、Aspect:切面=Pointcut+Advice,对很多个JoinPoint进行增强,形成一个切面;

5、Target:目标对象,被代理的目标对象;

6、Weaving:织入,把Advice加到Target上,创建出来代理对象的过程;

7、Proxy:一个target类被AOP织入增强后,创建出来的代理对象;

ps:环绕增强代表前四个增强的合体;执行真实对象的方法,可以给增强方法传参ProceedingJoinPoint来获取被增强方法;

3.2Pointcut语法

AspectJ是一个面向切面的框架,它扩展了Java语言。AspectJ定义了AOP语法;

括号中".."表示任意个参数,不带括号"xxx.."表示包含xxx以及xxx的任意子包,"*"代表一个单词;

比如:execution(* cn.volfcode.crm.service.*.*(..)) --- 代表(返回值 方法的全限定名(参数...))

4.Spring的AOP开发

4.1配置xml文件:

配置Aspect切面(增强的方式)、配置要被增强的方法、配置方法增强的具体时机(前置/后置....;并且需要引用要被增强的方法);

4.2.注解配置:

使用IoC和DI的注解,可以去掉bean的声明;(需要在xml文件配置对应的注解解析器)

在类上使用@Aspect注解配置切面,使用@Pointcut获取到所有要被增强的方法(贴在方法上!),使用@Before等注解贴在增强的方式(需要引用pointcut要被增强的方法才可!)

最后配置AOP注解解析器<aop:aspectj-autoproxy/>;

四、DAO持久化

1.事务

在一个事务方法中,调用了其他事务的方法,此时事务该如何传递,按照什么规则传播.

1.1事务传播规则情况一:

1、需要遵从当前事务REQUIRED: 必须存在一个事务,如果当前存在一个事务,则加入到该事务中,否则,新建一个事务;(使用比较多)

2、SUPPORTS: 支持当前事务。如果当前存在事务,则使用该事务否则以非事务形式运行;

3、MANDATORY: 必须要存在事务,如果当存在事务,就使用该事务,否则,抛出异常;

1.2事务传播规则情况二:不遵从当前事务

1、REQUIRES_NEW:不管当前是否存在事务,都会新开启一个事务 必须是一个新的事务;(使用的比较多)

2、NOT_SUPPORTED: 以非事务方式执行,如果当前存在事务,把当前事务暂停;

3、NEVER :不支持事务,如果当前存在事务,抛出一个异常;

1.3事务传播规则情况三:寄生事务(外部事务/内部事务/嵌套事务)

1、HESTED:寄生事务,如果当前存在事务,则在内部事务内执行;如果当前不存在事务则创建一个新的事务;

2、寄生事务可以通过数据库savePoint (保存点)来实现,寄生事务可以回滚的,但是他的回滚不影响外部事务.但是外部事务的回滚会影响寄生事务.

1.4<tx:method/>元素的属性(要被增强的方法)

1、name:事务管理的方法名称,支持使用通配符方式:*匹配方法的模式

2、propagation:事务的传播规则,默认REQUIRED

3、isolation:事务的隔离级别,默认DEFAULT跟随数据表

4、timeout:事务超时时间,默认跟随数据库

5、read-only:是否是只读事务,针对查询操作

6、rollback-for:遇到什么类型的异常做事务回滚,默认java.lang.RuntimeException

7、no- rol lback-for:遇到什么类型的异常不回滚

2.事务的配置

1、基于xml:配置增强的方式、配置增强的一些设置以及对应的Joinpoint、配置切面增强和切入点Pointcut;

2、基于注解:配置@Transactional(该注解可以贴在类/方法上)在service类上,配置tx注解解析器和事务管理实际类(IOC和DI的注解解析器也得配置);