java开发常用方法
-
newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h):
* loader: 用哪个类加载器去加载代理对象
* interfaces:动态代理类需要实现的接口
* h:动态代理方法在执行时,会调用h里面的invoke方法去执行 -
Method.invoke(Object obj, Object… args):
*obj:从中调用底层方法的对象,必须是实例化对象
*args: 用于方法调用,是一个object的数组,因为参数有可能有多个 -
InvocationHandler.invoke(Object proxy, Method method, Object[] args):
*proxy 代理的真实对象
*method 代理的方法
*args 代理方法中所接受的参数 -
startTransaction(): 开启事务
-
commitAndClose(): 关闭事务
-
rollbackAndClose(): 回滚事务
-
getClass(): 取得当前对象所属的Class对象
-
getClassLoader():取得该Class对象的类装载器
-
Resources :类为从类路径中加载资源,提供了易于使用的方法
-
Resources.getResourceAsStream():对于简单的只读文本数据
-
SqlSessionFactoryBuilder() :是利用XML或者Java代码来获得资源并构建SqlSessionFactory,作用就是一个构建器
-
openSession();:获取sqlSession对象
-
getMapper():是为了获取dao的代理对象,可以理解为反射使用dao的方法
注解
2. bean
标签的作用范围配置
<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl" scope="singleton"></bean>
- scope属性取值如下:
取值 | 说明 |
---|---|
singleton | 默认,表示单例的,一个Spring容器里,只有一个该bean对象 |
prototype | 多例的,一个Spring容器里,有多个该bean对象 |
request | web项目里,Spring创建的bean对象将放到request 域中:一次请求期间有效 |
session | web项目里,Spring创建的bean对象将放到session 域中:一次会话期间有效 |
globalSession | web项目里,应用在Portlet环境/集群环境;如果没有Portlet/集群环境,那么globalSession相当于session(新版本中已删除) |
-
不同scope的bean,生命周期:
-
singleton:bean的生命周期和Spring容器的生命周期相同
- 整个Spring容器中,只有一个bean对象
- 何时创建:加载Spring配置文件,初始化Spring容器时,bean对象创建
- 何时销毁:Spring容器销毁时,bean对象销毁
-
prototype:bean的生命周期和Spring容器无关。Spring创建bean对象之后,交给JVM管理了
- 整个Spring容器中,会创建多个bean对象,创建之后由JVM管理
-
-
何时创建:调用
getBean
方法获取bean对象时,bean对象创建- 何时销毁:对象长时间不用时,垃圾回收
注解 | 说明 |
---|---|
@RunWith | 用在测试类上,用于声明不再使用Junit,而是使用Spring提供的运行环境 |
@ContextConfiguration | 用在测试类上,用于指定Spring配置类、或者Spring的配置文件 |
-
@Component:用在类上,相当于bean标签`
-
@Controller:用在web层类上,配置一个bean(是
@Component
的衍生注解)` -
@Service
:用在service层类上,配置一个bean(是
@Component的衍生注解)
-
@Repository
:用在dao层类上,配置一个bean(是
@Component`的衍生注解) -
@Scope:相当于bean标签的
scope
属性` -
@PostConstruct
:相当于bean标签的
init-method属性
-
@PreDestroy
:相当于bean标签的
destory-method`属性 -
@Autowired
相当于property标签的ref
-
@Qualifier
结合
@Autowired使用,用于根据名称注入依赖
-
@Resource
相当于
@Autowired + @Qualifier`` -
@Value`相当于property标签的value
-
@Autowired:相当于property标签的ref
-
@Qualifier:结合
@Autowired
使用,用于根据名称注入依赖` -
@Resource
:相当于
@Autowired + @Qualifier` -
@Value:相当于property标签的value
-
@Configuration
被此注解标记的类,是配置类
-
@ComponentScan
用在配置类上,开启注解扫描。使用basePackage属性指定扫描的包
-
@PropertySource
用在配置类上,加载properties文件。使用value属性指定properties文件路径
-
@Import
用在配置类上,引入子配置类。用value属性指定子配置类的Class
-
@Bean`用在配置类的方法上,把返回值声明为一个bean。用name/value属性指定bean的id
@Conditional
说明
@Conditional
加在bean上,用于选择性的注册bean:- 符合Condition条件的,Spring会生成bean对象 存储容器中
- 不符合Condition条件的,不会生成bean对象
- 示例:
- 有一个类Person(姓名name,年龄age)
- 如果当前操作系统是Linux:就创建Person(linus, 62)对象,并注册bean
- 如果当前操作系统是Windows:就创建Persion(BillGates, 67)对象,并注册bean
- 步骤
- 创建Person类
- 创建两个Java类,都实现
Condition
接口:- WindowsCondition:如果当前操作系统是Windows,就返回true
- LinuxCondition:如果当前操作系统是Linux,就返回true
- 在核心配置类里创建两个bean
- 一个bean名称为bill,加上
@Conditional(WindowsCondition.class)
- 一个bean名称为linus,加上
@Conditional(LinuxCondition.class)
- 一个bean名称为bill,加上
@Profile
说明
- 在开发中,我们编写的工程通常要部署不同的环境,比如:开发环境、测试环境、生产环境。不同环境的配置信息是不同的,比如:数据库配置信息;如果每次切换环境,都重新修改配置的话,会非常麻烦,且容易出错
- 针对这种情况,Spring提供了
@Profile
注解:可以根据不同环境配置不同的bean,激活不同的配置@Profile
注解的底层就是@Conditional
- 例如:
- 定义三个数据源:
- 开发环境一个
DataSource
,使用@Profile
配置环境名称为dev
- 测试环境一个
DataSource
,使用@Profile
配置环境名称为test
- 生产环境一个
DataSource
,使用@Profile
配置环境名称pro
- 开发环境一个
- 在测试类上,使用
@ActiveProfiles
激活哪个环境,哪个环境的数据源会生效
- 定义三个数据源:
AOP详解
1) 通知的种类
通知的语法
@通知注解("切入点表达式")
通知的类型
名称 | 注解 | 说明 |
---|---|---|
前置通知 | @Before | 通知方法在切入点方法之前执行 |
后置通知 | @AfterRuturning | 通知方法在切入点方法之后执行 |
异常通知 | @AfterThrowing | 通知方法在抛出异常时执行 |
最终通知 | @After | 通知方法无论是否有异常,最终都执行 |
环绕通知 | @Around | 通知方法在切入点方法之前、之后都执行 |
- 注意:
- 注解方式配置的通知,执行顺序是:
前置->最终->后置/异常
- 如果想要指定执行的顺序,就使用环绕通知
- 注解方式配置的通知,执行顺序是:
2) 切点表达式的抽取
- 同xml的AOP一样,当多个切面的切入点表达式相同时,可以将切入点表达式进行抽取;
- 抽取方法是:
- 在增强类(切面类,即被
@Aspect
标的类)上增加方法,在方法上使用@Pointcut
注解定义切入点表达式, - 在增强注解中引用切入点表达式所在的方法
- 在增强类(切面类,即被
六、Spring的事务管理
- 事务的作用:保证事务里多个操作,要么全部成功,要么全部失败
- 目标:
- 了解事务管理的API
- 理解事务的传播行为
1. 编程式事务管理【了解】
- 所谓事务管理,即:按照给定的事务规则,来执行提交或回滚操作。其中:
- “给定的事务规则”:用
TransactionDefinition
表示 - “按照…来执行提交或回滚操作”:用
PlatformTransactionManager
来完成 TransactionStatus
用于表示一个运行着的事务的状态
- “给定的事务规则”:用
关于编程式事务的说明
-
编程式事务管理:通过编写代码的方式实现事务管理
-
编程式事务管理,因事务管理与业务功能耦合性太强,不方便维护,目前已经基本不用
spring 2.0 就已经提供了 xml配置的声明式事务管理的支持
-
如果想要了解Spring的编程式事务,可参考《资料/spring02_transaction_program》
-
-
以下API仅做介绍了解,用于了解Spring事务相关的API,并回顾事务相关的概念
PlatformTransactionManager
- 是Spring提供的事务管理器接口,它提供了我们常用的操作事务的方法:开启事务、提交事务等
- 注意:
PlatformTransactionManager
是接口类型,不同的dao层技术有不同的实现,例如:- dao层是jdbcTemplate或Mybatis时,实现类是:
DataSourceTransactionManager
- dao层是Hibernate时,实现类是:
HibernateTransactionManager
- dao层是jdbcTemplate或Mybatis时,实现类是:
方法 | 返回值 | 说明 |
---|---|---|
getTransaction(TransactionDefinition td) | TransactionStatus | 开启事务,并得到事务状态 |
commit(TransactionStatus status) | 提交事务 | |
rollback(TransactionStatus status) | 回滚事务 |
TransactionDefinition
- 事务的定义信息对象,提供了以下常用方法:
方法 | 参数 | 返回值 | 说明 |
---|---|---|---|
getIsolationLevel() | int | 获取事务的隔离级别 | |
getPropogationBehavior() | int | 获取事务的传播行为 | |
getTimeout() | int | 获取超时时间 | |
isReadOnly() | boolean | 是否只读的事务 |
事务的隔离级别:
事务的四大特性:ACID
A:原子性。表示事务是不可分割的
C:一致性。表示事务提交前后,数据/状态是一致的
I:隔离性。表示事务并发时,理论上应该是相互独立、不可分割的
D:持久性。表示事务一旦提交,数据就永久保存到磁盘文件上
当隔离性不彻底时,事务之间会相互干扰,造成的问题,就是事务并发的问题:
- 脏读:一个事务里读取到另外一个事务未提交的数据
- 不可重复读:一个事务里多次读取到的数据不一致,受到了其它事务update干扰
- 幻读:一个事务里多次读取的数据不一致,受到了其它事务insert、delete干扰
设置隔离级别,可以解决事务并发问题
ISOLATION_DEFAULT
:默认事务隔离级别- MySql默认隔离级别:
repeatable read
- Oracle默认隔离级别:
read committed
- MySql默认隔离级别:
ISOLATION_READ_UNCOMMITTED
:读未提交–存在脏读、不可重复读、幻读ISOLATION_READ_COMMITTED
:读已提交–存在不可重复读、幻读ISOLATION_REPEATABLE_READ
:重复读–存在幻读ISOLATION_SERIALIZABLE
:串行化–没有并发问题
事务的传播行为:
用于解决业务方法调用业务方法时,事务的统一性问题的
以下三个,是要当前事务的
PROPAGATION_REQUIRED
:需要有事务。默认- 如果有事务,就使用这个事务
- 如果没有事务,就创建事务。
PROPAGATION_SUPPORTS
:支持事务- 如果有事务,就使用当前事务,
- 如果没有事务,就以非事务方式执行(没有事务)
PROPAGATION_MANDATORY
:强制的- 如果有事务,就使用当前事务
- 如果没有事务,就抛异常
以下三个,是不要当前事务的
PROPAGATION_REQUIRES_NEW
:新建的- 如果有事务,就把事务挂起,再新建事务
- 如果没有事务,新建事务
PROPAGATION_NOT_SUPPORTED
:不支持的- 如果有事务,就把事务挂起,以非事务方式执行
- 如果没有事务,就以非事务方式执行
PROPAGATION_NEVER
:非事务的- 如果有事务,就抛异常
- 如果没有事务,就以非事务方式执行
最后一个,是特殊的
PROPAGATION_NESTED
:嵌套的- 如果有事务,就在事务里再嵌套一个事务执行
- 如果没有事务,就是类似
REQUIRED
的操作
事务运行的超时时间:
超时后事务自动回滚
- 默认值-1,表示没有超时限制
- 如果有,可以以秒为单位进行设置
是否只读:
- 如果设置为只读,那么方法只能查询,不能增删改
- 通常是查询方法设置为只读
TransactionStatus
- 提供了查询事务具体运行状态的方法,常用方法如下:
方法 | 返回值 | 说明 |
---|---|---|
hasSavePoint() | boolean | 事务是否有回滚点 |
isCompleted() | boolean | 事务是否已经完成 |
isNewTransaction() | boolean | 是否是新事务 |
isRollbackOnly() | boolean | 事务是否是 要回滚的状态 |
小结
- PlatformTransactionManager:平台事务管理器,是接口,规定了开启事务、提交事务、回滚事务的方法
- 如果dao层用的是JdbcTemplate/Mybatis:注册
DataSourceTransactionManager
- 如果dao层用的是Hibernate:注册
HibernateTransactionManager
- TransactionDefinition:事务的定义信息,即:你想要开启什么样的事务
- 隔离级别:通常是默认
- 传播行为:通常设置为默认的,propagation_required
- 超时时间:单位是秒。通常是默认值-1,表示不限制
- 是否只读:通常查询方法设置为true;非查询设置为false