SSM-Spring一些知识点
Posted wonderfulu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SSM-Spring一些知识点相关的知识,希望对你有一定的参考价值。
Spring IOC入门
1)创建一个新的工程
2)导入SpringIOC核心坐标
3)准备一个类
4)在配置文件中声明bean
1.IOC原理
IOC(控制反转)不是什么技术,而是一种设计思想。它的目的是指导我们设计出更加松耦合的程序。
控制:指的是控制权,在java中可以简单理解为 对象的控制权限(比如对象的创建、销毁等权限)
反转:指的是将对象的控制权由原来的 程序员在类中主动控制 反转到 由Spring容器来控制。
原来我们需要一个对象,就自己在类中new,现在我需要一个对象,我们不在直接new,而是问spring容器要,Spring会提前把所有的对象创建好,等待我们的调用。
优点:IOC 或 依赖注入把应用的代码量降到最低。它使应用容易测试,单元测试不再需要单例和
JNDI 查找机制。最小的代价和最小的侵入性使松散耦合得以实现。 IOC 容器支持加载服务时
的饿汉式初始化和懒加载。
2.Spring的原理分析
1)读取配置文件,读取到bean的class部分,根据class指定的全类名去内存中寻找
2)如果找到了就会利用反射技术创建出这个对象
3)将创建出的对象存到Map结构中,作为值(取bean标签的id属性为键)
3.API
两个接口
BeanFactory
这是Spring的顶层接口,定义了SpringIOC的最核心功能
BeanFactory创建对象的时机:当第一次调用对象的时候创建(getBean)
BeanFactory面向Spring自身使用
ApplicationContext
这是beanFactory的扩展接口,扩展了beanFactory的功能
ApplicationContext创建对象的时机:Spring容器以初始化就创建所有的对象
ApplicationContext面向程序员
三个实现类
作用完全一样:读取配置文件,初始化核心容器
不同点在于读取配置文件的位置不一样
ClassPathXmlApplicationContext
在类路径下读取一个xml作为配置文件
FileSystemXmlApplicationContext
在一个磁盘目录下读取一个xml作为配置文件
AnnotationConfigApplicationContext
读取一个注解类作为配置文件
4.创建对象的方式
直接调用构造方法创建对象
调用静态工厂创建对象
调用实例化工厂创建对象
5.Bean的作用域
singleton(默认) 创建出的实例为单例模式, IOC只创建一次,然后一直存在
prototype 创建出的实例为多例模式, 每次获取bean的时候,IOC都给我们重新创建新对象
request(web) web项目中,Spring 创建一个 Bean 的对象,将对象存入到 request 域中.
session (web) web项目中,Spring 创建一个 Bean 的对象,将对象存入到 session 域中.
globalSession (用于分布式web开发) 创建的实例绑定全局session对象
6.Bean的生命周期
Singleton 单例
出生:Spring容器初始化就产生了
死亡:Spring容器销毁就死亡了
prototype 多例
出生:调用的时候产生
死亡:当对象没有引用的时候,由垃圾回收器自动回收
7.依赖注入
Dependency Injection(DI):就是给一个对象中的各种属性赋值的过程
1).构造函数注入
2).Set方法注入
两种方式的对比
构造函数对传入的参数的数量有严格的要求
Set方法其实是先new对象,然后在调用set设置,它不会参与对象的创建过程
在 Spring 中如何注入一个 java 集合?
Spring 提供以下几种集合的配置元素:
<list>类型用于注入一列值,允许有相同的值。
<set> 类型用于注入一组值,不允许有相同的值。
<map> 类型用于注入一组键值对,键和值都可以为任意类型。
<props>类型用于注入一组键值对,键和值都只能为 String 类型。
8.配置文件分模块
问题
所有的配置都在一个文件中,会导致文件变大,而且后面维护不方便
解决方案
把一个大的配置文件拆成多个小的配置文件
方案一 同时传入多个配置文件
方案二 主从配置文件的形式
总结:
同一个配置文件不允许bean的id重复,如果重复,直接报错
不同一个配置文件如果出现id重复,会导致后面的bean覆盖前面的bean
9.注解创建对象
@Component
表示向Spring中注册组件,相当于XML中的<bean id="" class=""></bean>
ean的id默认为当前类名的首字母小写
当然也可以是用@Component("自定义名称")的形式指定id名
@Controller @Service @Respository
这三个注解的作用跟@Component完全一样,都表示向Spring中注册组件,只不过这三个更加有语义性。
@Controller 一般标注在web层的类上
@Service 一般标注在service层的类上
@Repository 一般标注在dao层的类上
我们推荐使用上面这三个,只有当一个类不属于三层架构的时候才使用@Component
10.对象的生存范围
单例@Scope("singleton")
多例@Scope("prototype")
11.使用注解声明依赖注入
@AutoWired
用来表示根据类型进行依赖注入,可以标注在属性上,也可以标注在方法上
标注在属性上
Spring会按照类型在IOC容器中进行寻找
如果找不到,就报错
如果找到了
而且正好找到了一个,就进行依赖注入
如果找到了多个,再根据name进行匹配
如果匹配成功,就注入
匹配不成功就报错
如果标注在属性上,set方法可以省略
寻找顺序 byType byName
标注在方法上
如果@Autowired标注在一个方法上,这个方法会自动执行
如果这个方法需要参数
Spring会按照类型在IOC容器中进行寻找
如果找不到,就报错
如果找到了
而且正好找到了一个,就进行依赖注入
如果找到了多个,再根据name进行匹配
如果匹配成功,就注入
匹配不成功就报错
寻找顺序 byType byName
@Qualifier
标注在属性上
必须和@Autowired连用,表示在按照类型查找的基础上,再根据指定的name进行查找
@Resource(了解)
先按照名称进行查找,如果查找到就注入
如果查不到,再按照类型进行匹配
如果匹配成功,就注入
如果匹配到多个或者一个也匹配不上,就报错
如果指定了查找的name,那么他就只会按照name查找
这个注解是java提供的,而且在java9版本之后已经废弃
@Value注入简单数据类型
12.Spring的纯注解的解释
@Configuration
用于指定一个类是配置类。Spring在启动的时候,会默认加载所有配置类
@Import
用于导入其它的配置类
@PropertySource
在classpath下寻找配置文件,导入配置文件中的信息
13.spring整合单元测试
分析原理
原来点击run的时候,底层调用的对象其实是Runner的子类,默认ParentRunner。他是不认识Spring环境的,也就无法从IOC中获取bean。
要想从IOC中获取到bean,首先要认识Spring环境
Spring重写了一个Runner,这个Runner认识Spring,有它就可以从IOC中获取对象。
操作步骤
加入Spring和Junit的整合包
指定采用Spring的Runner
@Runner 让你指定运行器
指定配置文件
当用来指定xml配置文件
@ContextConfiguration("classpath:***.xml")
当用来指定class配置文件
@ContextConfiguration(classes=***.class)
测试
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:appliciationContext.xml") public class ServiceTest
14.AOP概念
Aop(面向切面编程),他是一种指导思想.
它的目的是希望在不修改原有代码的基础上,对代码进行功能增强.
Spring 的 AOP 是对 AOP 思想的一种很好的实现。
他底层采用了 GDK 和 CGLIB 动态代理技术
也就是说, Spring 会根据被代理类是否有接口来自动选择是使用 cglib 或 GDK
如果有接口, 就用 GDK, 因为它效率高; 如果没接口, 就选择 cglib, 因为没办法。
15.AOP中的术语
目标对象
被代理对象
连接点
被代理对象中的方法
切入点
被代理对象中的一部分方法(要进行功能增强)
增强(通知)
就是一个功能(增强类\增强方法)
织入
就是将增强功能填充到目标方法(切入点)中的过程
代理对象
经过织入然后通过代理产生的对象
切面
切点+增强
描述了增强功能在什么时候加入到切点的哪个位置
16.四大通知
说明
before前置通知:在目标方法执行之前运行
after-returning 后置通知:在目标方法正常返回运行
after-throwing异常通知:在目标方法发生异常时执行
after最后通知:始终在最后执行
try
前置通知
//目标方法执行
后置通知
catch (Exception e)
异常通知
finally
最后通知
<aop:config> <aop:pointcut id="pt" expression="execution(* com.jia.dao.impl.*.*(..))"/> <aop:aspect id="hghjg" ref="logger"> <!--<aop:before method="beforeMethod" pointcut-ref="pt"/> <aop:after-returning method="afterMethod" pointcut-ref="pt"/> <aop:after-throwing method="exceptionMethod" pointcut-ref="pt"/> <aop:after method="lastMethod" pointcut-ref="pt"/> -->
<!--环绕通知-->
<aop:around method="aroundMethod" pointcut-ref="pt"/> </aop:aspect> </aop:config>
17.环绕通知
说明
这是一种特殊的通知,它允许程序员通过代码的形式实现四大通知的功能.
18.AOP工作原理(重点)
开发阶段
开发增强方法
开发业务方法分离开发
配置将增强和业务方法柔和在一起
运行阶段
Spring会时刻监控切点方法的执行,一旦发现程序运行到了切点方法,Spring会立即将增强方法放置到切点方法的前后左右位置,实现一个组装运行的原理.
19.AOP开发步骤
开发目标对象(方法)
开发增强对象
配置
20.事务
使用Spring的Aop配置事务(xml版本)
加入切点表达式解析包
编写目标对象放入IOC容器
编写增强对象放入IOC容器
可以用Component注解放入IOC容器
使用Spring配置AOP
定义切点
指定增强类
测试
2)使用Spring的AOP配置事务(注解版本)
将增强对象变成切面对象
在增强类上加入Aspect注解,把增强类变成切面
在切面对象上使用注解配置AOP
在切面对象加入方法,方法参数是Pjp,方法内写try..catch..finally
在方法上加入注解Around(“execution(* 要增强方法的全限定名)”)
删除XML中的aop配置
开启aop注解支持
在配置文件中加入<aop:aspect-autoproxy>
测试
21.介绍几款数据源
C3P0(推荐)
世界闻名的连接池,有池技术,适合生产环境
Druid(推荐)
阿里巴巴的一款数据源,有池技术,适合生产环境
Spring-jdbc
Spring自带的一款数据源,没有池技术,适合开发\测试环境
Dbcp
Tomcat自带的一款数据源,有池技术
22. Spring中的事务控制方式
在Spring中有两种事务控制方式:编程式事务和声明式事务.
编程式事务需要我们在代码中手动编写事务控制代码,在开发中很少使用
声明式事务则是通过配置的形式进行事务管理,可以使得事务管理和业务代码解耦合.
声明式事务使用的思想是AOP.
23.Spring中事务相关的API(了解)
PlatformTransactionManager
Spring事务管理的顶级接口,它的子类主要负责事务管理.
我们一般采用的事务管理器是DataSourceTransactionManager
TransactionDefinition
主要负责事务信息的定义
事务隔离级别
int ISOLATION_DEFAULT = -1;//默认级别,它会根据数据库的默认级别进行选择
int ISOLATION_READ_UNCOMMITTED = 1; //读未提交
int ISOLATION_READ_COMMITTED = 2;//读已提交(oracle默认级别)
int ISOLATION_REPEATABLE_READ = 4;//可重复读(mysql默认级别)
int ISOLATION_SERIALIZABLE = 8;//串行化
事务传播行为
当一个方法被另一个方法调用时,应该如何进行事务控制
PROPAGATION_REQUIRED(必须有事务这是默认值)
如果存在一个事务,则加入到当前事务,如果没有事务则开启一个新事务
PROPAGATION_SUPPORTS(支持有事务)
如果存在一个事务,则加入到当前事务,如果没有事务则非事务运行
事务只读性
事务是否只读,建议对于查询操作设置为只读事务
事务超时
设置事务超时时间,需要数据库底层的支持
默认值为-1,即不限制
TransactionStatus
用来描述事务在某一个时刻的状态
三个API之间的关系
事务管理器通过读取事务定义的参数进行事务管理.管理后的事务会在不同的时刻拥有不同的事务状态
24.Spring声明式事务的使用步骤
Spring的声明式事务使用的是AOP思想,遵循三步骤
准备目标类(业务类)
准备增强类(Spring提供,即使他的事务管理器)
配置切面
25.Spring的声明式事务的入门案例
加入切点表达式解析包
在service接口添加业务
@Override public void transfer(String sourceName, String targetName, Float amount) //查询两个余额 Account sourceAccount = accountDao.findByName(sourceName); Account targetAccount = accountDao.findByName(targetName); //做增减 sourceAccount.setBalance(sourceAccount.getBalance()-amount); targetAccount.setBalance(targetAccount.getBalance()+amount); //更新 accountDao.update(sourceAccount); int s=1 / 0; accountDao.update(targetAccount);
在XML中使用声明式事务进行配置
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx https://www.springframework.org/schema/tx/spring-tx.xsd"> <!--添加包扫描--> <context:component-scan base-package="com.jia"/> <!--dataSource--> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql:///spring"/> <property name="username" value="root"/> <property name="password" value="root"/> </bean> <!--jdbcTemplate--> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"/> </bean> <!--事务管理器--> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <!--配置增强--> <!--目的是向事务管理器传递管理参数--> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="*"/> </tx:attributes> </tx:advice> <!--配置增强和切入点--> <aop:config> <!--切入点--> <aop:pointcut id="pt" expression="execution(* com.jia.service.impl.*.*(..))"/> <!--配置切面,只是事务专用的配置--> <aop:advisor advice-ref="txAdvice" pointcut-ref="pt"/> </aop:config> </beans>
26.声明式事务注解版
添加包扫描
<!--添加包扫描-->
<context:component-scan base-package="com.jia"/>
添加事务声明式事务驱动支持
<tx:annotation-driven>
将dao层换成注解
@Repository
将service层换成注解
@Service
在service类上进行事务配置
@Transactional(readOnly = false)
在需要声明事务的方法上加入注解Transactional(),也可以放在类上
括号里可以写上transaction-manager="transactionManager"
read-only="false" 只读(查询)
timeout="-1" 超时(数据库)
propagation="REQUIRED" 传播行为
isolation="DEFAULT" 隔离级别
27.纯注解版本
创建一个配置类
@ComponentScan("com.jia") @EnableTransactionManagement public class SpringConfig @Bean public DataSource dataSource() DruidDataSource dataSource = new DruidDataSource(); dataSource.setDriverClassName("com.mysql.jdbc.Driver"); dataSource.setUrl("jdbc:mysql:///spring"); dataSource.setUsername("root"); dataSource.setPassword("root"); return dataSource; @Bean public JdbcTemplate jdbcTemplate(DataSource dataSource) JdbcTemplate jdbcTemplate = new JdbcTemplate(); jdbcTemplate.setDataSource(dataSource); return jdbcTemplate; @Bean public DataSourceTransactionManager transactionManager(DataSource dataSource) DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager(); dataSourceTransactionManager.setDataSource(dataSource); return dataSourceTransactionManager;
在类名上面加入注解
包扫描 @ComponentScan(“包名”)
声明式事务驱动 @EnableTransactionManager
去掉xml所有配置
测试
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes=SpringConfig.class) public class AccountServiceTest
以上是关于SSM-Spring一些知识点的主要内容,如果未能解决你的问题,请参考以下文章
SSM-Spring-06:Spring的自动注入autowire的byName和byType
SSM-Spring-14:Spring中默认自动代理DefaultAdvisorAutoProxyCreator