1.spring核心概念
代码书写耦合度偏高,需要降低耦合度,在程序中不要主动new对象,转换为外部提供对象
2.IOC控制反转
spring提供了IOC容器来充当外部,IOC容器负责对象的创建,初始化工作,被创建的对象或管理的对象统称为bean对象
3.di依赖注入
在容器中建立的bean与bean对象中之间的依赖关系称为依赖注入
3.2
1.beanFactory快速入门-对IOC和di的实现
导入spring-contect 的jar包
定义UserService接口和UserServiceImp实现类
创建beans.xml配置文件,将UserServiceImp的地址配置到xml中
编写测试代码,创建BeanFactory,加载配置文件,获取UserService实例对象,调用方法
2.applicationcontext快速入门
他称为spring容器,里面封装了beanfactory,功能更加强大,使用此类开发时,需要将xml配置文件写成applicationContext.xml
3.beanfactory和applicationcontext的关系
beanfactory是spring的早起接口,称为bean工厂,applicationcontext是后期更加高级的接口,称为spring的容器
applicationcontext在beanfactory的基础上对其功能经行了扩展,如监听功能,国际化功能,beanfactory更偏向于底层,applicationcontext的api大多数是对底层的封装
bean创建的主要逻辑都封装在beanfactory中,applicationcontext不仅继承了beanfactory,而且还在内部维护着beanfactory,所以applicationcontext和beanfactory既有继承关系,又有融合关系
bean初始化时机不同,beanfactory实在首次调用getbean创建的,applicationcontext是配置 文件加载,容器创建将bean初始化
4、三个常用applicationcontext
classpathxmlapplicationcontext:加载类路径下的xml配置的applicationcontext
filesystemxmlapplicationcontext:加载磁盘文件的xml配置的applicationcontext
annotationconfigapplicationcontext:加载注解类的applicationcontext
当导入不同环境的包时,applicationcontext继承体系也会发生变化
3.3
1.基于xml的bean的一些配置
id:getbean时的唯一标识,当没有配置id时,该标识为bean的impl的全限定名
beanname:是bean的别名,当没有配置id(bean的唯一表识)时,配置的别名第一个为id,通过id可以getbean实例
scope:bean的作用范围,singleton表示单例,只创建一个实例(创建时机,newspring容器时),prototype表示原型,可以创建多个实例(创建时机,getbean时)
lazy-init:是否延迟加载,beanfactory作为容器时无效
init-method:bean实例化后自动执行的初始化方法,method指定方法名,他是在bean的构造器之后执行
补充:还可以通过实现接口类实现initializirable接口,重写afterpropertiesset方法执行初始化工作
destroy-method:bean实例销毁前的方法,method指定方法名,当bean销毁时,不会执行该方法,需要通过子类显示调用close方法
2.spring的bean的实例化方式
构造方法实例化:底层通过构造方法对bean进行实例化,有参构造时,需要再bean中配置constructor-arg,name是有参构造方法的形参,value是值
工厂方式实例化:底层通过调用自定义的工厂方法对bean进行实例化,好处就是可以在实例化前后执行一些代码,有些bean不是自定义的,需要自己配置,工厂方式可以实现
工厂方式分为三种
静态工厂:定义自己的工厂类,定义静态方法返回bean实例,配置工厂类bean的factory-method,值为该方法名
实例工厂:定义自己的工厂类,定义普通方法返回bean实例,配置工厂类bean,再配置工厂类下的方法bean,factory-bean为工厂类bean的id,factory-method为方法名
实现factorybean规范延迟实例化bean:自定义工厂类实现factorybean接口,重写getobject方法,返回bean实例,配置工厂类bean即可
3.bean的依赖注入,
通过set方法注入,bean下配property
通过构造器的方法注入,bean下配constructor-arg
不同的数据类型在配置文件中有不同的格式
普通类型通过value指定,引用类型通过ref指定,集合类型通过不同标签指定(当集合下是引用类型时,可以通过配置bean方式指定)
tips:建议使用set注入的方式
4.依赖自动装配
删除bean下配置的property,添加属性aotuware,bytype:通过类型自动装配,byname:通过名字装配
细节:自动装配只能用于引用类型,不能用于简单类型
使用bytype时,必须保证容器内相同的bean唯一,推荐使用
使用byname时,必须容器内具有指定名称的bean
自动转配优先级低于set注入和构造器注入,同时出现时自动装配将失效
5.bean的生命周期
初始化容器:
创建对象(内存分配)
执行构造方法
执行属性注入(set操作)
执行bean的初始化方法
容器关闭前才会触发bean的销毁:
手动关闭:a.子接口调用close操作
注册关闭钩子,在虚拟机关闭前先关闭容器再退出虚拟机:调用registershutdownhook
3.6
1.纯注解开发模式
定义bean
在bookdaoimpl上使用
@component(下面三个表示更加详细的分类):把普通pojo实例化到spring容器中,相当于之前xml配置文件中的 <bean id="" class=""/> )
@controller:负责注册一个bean 到spring 上下文中
@service:Spring要创建UserServiceImpl的的实例时,bean的名字默认叫做"userService"
@repository:让Spring创建一个名字叫“userDao”的UserDaoImpl实例
spring3.0开启了纯注解开发模式,使用java配置类来代替配置文件
@configuration代替了 applicationcontext.xml的基础配置
@componentscan(“com.wzm”)代替了包扫描
使用AnnotationConfigApplicationContext获取bean
2.bean的作用范围
在bookdaoimpl上使用@scope,singleton表示单例,prototype表示多例
3.定义生命周期
在bookdaoimpl里定义方法init,destory,在方法上分别加上注解postconstruct和predestory
4.依赖注入
自动装配:在bookdaoimpl里使用@autowired
如果有多个实体类,使用@qualifier(“bookdao2”)
基本类型装配使用@value()
读取properties文件:在java配置类上@propertysource(“文件名”)
5.第三方bean管理
定义第三方管理类,定义管理方法返回你要管理的bean,在管理方法上@bean
使用导入式,在java配置类上@import(第三方管理类.class),可以使用数组导入多个第三方类
6.第三方bean的依赖注入
基本类型:使用属性,在上面加@value(“配置”)
引用类型:用方法形参,会按类型自动装配
3.7
1.spring整合mybatis思路分析
自己看源码spring-mybatis
2.aop:面向切面编程
在不惊动原始设计的基础上做功能增强(无入侵式编程)
快速入门:
导入aspectjweaver坐标和springaop(在spring-context中)坐标
定义连接点方法:BookDaoImpl里的方法
定义共性功能:新建aop包下的Myadvice类下的method方法(表示共性功能)需要再此类加上@component告诉spring这是一个bean,@aspect告诉spring这是aop
定义切入点方法:private void pt();加上注解@Pointcut(“execution(void com.wzm.dao.BookDao.update())”)
绑定切入点与通知关系:在method方法上@before(“pt()”),表示在update方法执行方法之前
最后需要再配置类上加上@EnableAspectJAutoProxy告诉spring这是使用注解开发的aop
3.aop工作流程
目标对象:原始功能去掉共性功能对应的类产生的bean对象
代理:目标对象无法直接完成工作,需要对其功能进行回填(增加功能),需要通过代理对象实现
spring容器启动
读取所有切面的切入点
初始化bean,判定bean对应类的方法是否匹配到切入点
匹配失败,创建对象
匹配成功,创建目标对象的代理对象
获取bean的执行方法
获取bean调用方法并执行
获取的bean是代理对象时,会对方法进行增强内容并执行
4.切入点表达式
*:可以作为前缀或者后缀的通配符出现
execution(public * com.wzm.*.UserService.find*(*))
匹配com.wzm下的任意包的UserService接口的find开头的一个参数的方法任意返回类型
..:简化包名与参数书写
execution(public User com..UserService.findById(..)
匹配com包下的任意包的UserService接口下的所有名称findByid方法
细节:
描述切入点通常描述接口而不是实现类
返回值类型对于增删改类使用精准匹配,查询类使用*通配快速描述
包名书写尽量不适用..,效率过低,常用*做单个包的描述
接口名、类名书写名称与模块相关采用*匹配,例UserService写成*Service,绑定业务层接口名
方法名书写以动词进行精准匹配,名称采用*匹配,例getById写成getBy*,selectAll就是原名
5.aop通知类型
前置通知@before
后置通知@after
环绕通知@around(常用)
@around(“pt()”)
public void around(ProceedingJoinPoint pt){pt.preceed();} , pt.preceed()表示调用切入点方法,其返回值是切入点返回值
返回后通知
抛异常后通知
6.aop通知获取参数数据
before使用接口joinpoint jp 调用getArgs方法可以获得切入点方法的参数
around使用joinpoint的子接口proceedjoinpoint的getArgs获得参数
3.8
1.spring事务
在数据层或者业务层保证一系列数据库操作同时成功同时失败
快速入门:
在配置类上加@EnableTransactionManagement开启注解事务驱动
在需要开启事务的接口的方法上加@Transactional
配置事务管理器,在jdbcconfig配置类下添加方法
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource){
DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
transactionManager.setDataSource(dataSource);
return transactionManager;
}
细节:有些异常事务并不会回滚,需要再@Transactional()配置属性,rollbackfor(class)设置事务回滚异常
2.spring事务角色
事务管理员:发起事务方,通常指代业务层开启事务的方法
事务协调员:加入事务方,通常指代数据层方法,也可以是业务层方法
3.事务传播行为
需求:无论转账是否成功,都需要记录下来
在logService接口的log方法加@Transactional(propagation = Propagation.REQUIRES_NEW)表示新开一个事务,不会加入到事务管理员中
还有一些其他属性,自行百度