spring02
1、在spring容器中的一个bean的整个生命周期
1、启动spring容器
2、bean实例化
3、装配属性
4、BeanNameAware:setBeanName
5、BeanFactoryAware:setBeanFactory
6、ApplicationContextAware:setApplicationContext
7、。。。。。。
8、调用init方法
9、后处理bean:BeanPostProcessor:改变一个bean的行为
10、从spring容器中把一个bean提取出来,调用方法
11、销毁
2、springAOP:面向切面编程
1、应用场景
1、应用场景1
Transaction tx = session.beginTransaction();
session.save/update/delete/query
tx.commit();
目标:
程序员只写session.save/update/.....
事务谁写?
2、应用场景2
1、开启日志
2、开启安全性的框架
3、检查有没有权限
4、如果有权限,则查看工资
如果没有权限,则不能查看工资
showSalary(){
查看工资
}
logging(){
//写日志
}
security(){
//安全性框架
}
access(){
//权限检查
}
最后会形成一个方法:(该方法是动态形成的):
把上面所有的方法结合在一起了
2、aop的原理:
动态代理模式
jdk动态代理
目标接口
目标类
拦截器
代理类实现了目标接口
cglib动态代理
目标类
拦截器
代理类是目标类的子类
3、动态代理模式确实可以解决上面的问题,可以把下面的场景全部的分开来写
1、开启日志
2、开启安全性的框架
3、检查有没有权限
4、如果有权限,则查看工资
但是实际的业务系统是比较复杂的,在ProxyFactoryBean中,生成代理对象的方法中需要做很多判断性的工作
而且这些工作并不好做,所以动态代理模式是AOP的理论基础,但是并不能直接应用于企业开发
4、aop的概念
1、目标类
2、切面:除了目标类以外,其他的都是切面,是一个类
事务
日志
安全性框架
权限
3、通知
切面中的方法就称为通知
public class Transaction {//切面
public void beginTransaction(){//通知
System.out.println("begin transaction");
}
public void commit(){//通知
System.out.println("commit");
}
}
4、连接点
客户端调用哪个方法,哪个方法就是连接点
@Test
public void testSave(){
/**
* 1、创建目标对象
* 2、创建事务
*/
Object target = new PersonDaoImpl();
Transaction transaction = new Transaction();
PersonDao personDao = (PersonDao)ProxyFactoryBean.getInstance(target, transaction);
personDao.savePerson();//连接点
}
5、切入点:是一个条件
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
//if语句就是切入点
if(method.getName().equals("")||method.getName().equals()){
/**
* 1、启动事务
*/
transaction.beginTransaction();
/**
* 2、调用目标方法
*/
method.invoke(target, args);
/**
* 3、提交事务
*/
transaction.commit();
}else{
/**
* 2、调用目标方法
*/
method.invoke(target, args);
}
return null;//返回的是方法的返回值
}
6、织入
形成代理对象方法体的过程
5、aop存在的意义
在做一件事情的过程中,这个事情可以分为目标类和很多切面,
而目标类和很多切面是完全松耦合的,这样的方式有利于软件开发
当形成代理对象的方法体的过程就把目标方法和通知结合在一起了
6、spring的aop
1、实现hibernate中的事务的重用
2、各种通知
1、前置通知
1、在spring配置文件中的配置
<aop:before method="beginTransaction" pointcut-ref="perform"/>
2、该方法可以没有参数,也可以有参数,参数为JoinPoint,该参数为连接点
客户端调用哪个方法,哪个方法就是连接点
3、从连接点中可以获取的信息有
//连接点的参数列表
System.out.println(joinPoint.getArgs().length);
//得到目标对象
System.out.println(joinPoint.getTarget());
//得到方法的名称
System.out.println(joinPoint.getSignature().getName());
2、后置通知
1、后置通知的参数除了有JoinPoint以外,还可以有一个参数,该参数可以接收目标方法的返回值
<aop:after-returning method="commit" returning="val"/>
/**
* 后置通知
*/
public void commit(JoinPoint joinPoint,Object val){
System.out.println("commit");
System.out.println(val);
}
2、后置通知在目标方法执行之后执行
3、当目标方法遇到异常以后,后置通知将不再执行
3、异常通知
1、获取到目标方法抛出的异常信息
<aop:after-throwing method="throwingMethod" pointcut-ref="perform" throwing="ex"/>
/**
* 异常通知
*/
public void throwingMethod(JoinPoint joinPoint,Throwable ex) throws Throwable{
System.out.println(ex.getMessage());
}
2、该异常处理是完全独立于系统之外的处理方式,该异常处理和action,service,dao层都没有关系
和业务逻辑也没有关系,完全独立的
4、最终通知
无论目标方法是否有异常,都将执行,可以将资源的释放工作放在里面
5、环绕通知
/**
* 环绕通知
* JoinPoint
* ProceedingJoinPoint
*/
public void aroundMethod(ProceedingJoinPoint joinPoint) throws Throwable{
System.out.println("aaaa");
joinPoint.proceed();//用来执行目标方法的
}
1、环绕通知可以控制目标方法的执行
2、环绕通知也能得到JoinPoint里面的信息
7、各种例子
1、把action、service、dao层的类和接口放入到spring容器中
利用springAOP的异常通知处理异常
注意事项:
目标类是谁?
切面是谁?应该用哪个通知
2、创建service层和dao层,计算连接点的执行时间?
3、创建service层和dao层,权限处理的例子
public class PersonService{
private PersonDao personDao;
//当前的用户只有拥有了"query person"权限才能访问queryPerson方法
如果没有这个权限,是没有办法访问该方法的
@PrivilegeInfo(name="query person")
public void queryPerson(){
}
}
Privilege:
name
List<Privilege> privileges;
在客户端可以把用户拥有的权限放入到privileges中
4、利用springaop处理缓存
public class PersonDao{
@Cacheable(name="put")
public void savePerson(Person person){
//把person对象放入到数据库中
}
@Cacheable(name="get")
public void queryPerson(Long pid){
//从数据库中提取person对象
}
}
当检查到连接点上有注解@Cacheable,并且name的属性的值为"put"的时候
做两件事情:
1、把person放入到数据库中
2、把person放入到缓存中Map<Long,Person>
当检查到连接点上有注解@Cacheable,并且name的属性的值为"get"的时候
要做的事情:
先检查缓存中没有该值,如果有,则从缓存中把值提取出来
如果没有,则从数据库中提取出来
5、 打印出:xxxxx类的xxxxx方法在xxxxxx时间内被调用了多少次
只计算service层就可以了
8、理解
1、切面肯定是一个系统级别的重用的和业务逻辑没有关系的类
2、利用aop使得目标类和各个切面完全松耦合,这样设计的系统架构更好,更有利于团队开发,代码复用
spring02的更多相关文章
- spring-02
spring-02 1.谈谈你对 Spring 的理解 Spring 是一个开源框架,为简化企业级应用开发而生.Spring 可以是使简单的 JavaBean 实现以前只有 EJB 才能实现的功能.S ...
- Spring-02 第一个Spring程序
Spring-02 第一个Spring程序 第一个Spring程序 1.导入依赖 <dependency> <groupId>org.springframework</g ...
- JAVAEE——spring02:使用注解配置spring、sts插件、junit整合测试和aop演示
一.使用注解配置spring 1.步骤 1.1 导包4+2+spring-aop 1.2 为主配置文件引入新的命名空间(约束) 1.3 开启使用注解代替配置文件 1.4 在类中使用注解完成配置 2.将 ...
- Spring-02 Java配置实现IOC
Java配置 Spring4推荐使用java配置实现IOC Spring boot也推荐采用java配置实现IOC 在实际项目中,一般采用注解配置业务bean,全局配置使用Java配置. Java配置 ...
- Spring-02 -Spring 创建对象的三种方式 :1.通过构造方法创建/2.实例工厂/3.静态工厂
通过构造方法创建 1.1 无参构造创建:默认情况. 1.2 有参构造创建:需要明确配置 1.2.1 需要在类中提供有参构造方法 1.2.2 在 applicationContext.xml 中设置调 ...
- Spring02——Spring 中 Bean 的生命周期及其作用域
在前一篇文章中,我们已经介绍了 Spring IOC 的相关知识,今天将为个位介绍 Spring 中 Bean 的相关知识.关注我的公众号「Java面典」,每天 10:24 和你一起了解更多 Java ...
- 玩转spring boot——MVC应用
如何快速搭建一个MCV程序? 参照spring官方例子:https://spring.io/guides/gs/serving-web-content/ 一.spring mvc结合thymeleaf ...
- Spring学习总结(一)——Spring实现IoC的多种方式
控制反转IoC(Inversion of Control),是一种设计思想,DI(依赖注入)是实现IoC的一种方法,也有人认为DI只是IoC的另一种说法.没有IoC的程序中我们使用面向对象编程对象的创 ...
- (转)Spring 的 init-method 和 destory-method
背景:今天在项目中看到spring中bean在初始化和注销时候的方法定义,之前没有用过这种方式,在此记录下,方便后期查看! 关于在spring 容器初始化 bean 和销毁前所做的操作定义方式有三种: ...
随机推荐
- H5 浏览器开发文档
http://sja.co.uk/controlling-which-ios-keyboard-is-shown https://developer.apple.com/library/safari/ ...
- overflow-y:auto
overflow-x:auto; overflow-y:auto; X轴和Y轴自适应:
- Leetcode SortList
Sort a linked list in O(n log n) time using constant space complexity. 本题利用归并排序即可 归并排序的核心是将两部分合成一部分, ...
- 【BZOJ】1086: [SCOI2005]王室联邦
http://www.lydsy.com/JudgeOnline/problem.php?id=1086 题意:n个点的树,要求分块,使得每一块的大小在[b, 3b]内且块与某个点形成的块是连通的(某 ...
- Vijos 1092 全排列
题目链接 来个水题..难得的1Y. #include <cstdio> #include <cstring> #include <iostream> using n ...
- USACO 5.5 Hidden Password(搜索+优化)
水了好几下. 优化1:开始初始化的时候,如果左边那个也是最小值,那么此点就不用进队了. 优化2:如果队列里的位置,已经超过了后面位置的初始位置,那么后面这个位置也没用了. /* ID: cuizhe ...
- 深入浅出 - Android系统移植与平台开发(四)- Android启动流程
作者:唐老师,华清远见嵌入式学院讲师. 一.Android init进程启动 还是从Linux的启动开始吧.Linux被bootloader加载到了内存之后,开始运行,在初始化完 Linux运行环境之 ...
- URL编码:不同的操作系统、不同的浏览器、不同的网页字符集,将导致完全不同的编码结果。
URL编码:不同的操作系统.不同的浏览器.不同的网页字符集,将导致完全不同的编码结果. 因此如果Url中有中文或特殊字符,一定要自己调用函数编码解码,不要让浏览器帮你编码,否则出现了问题会浪费你很多时 ...
- [LintCode] 3Sum 三数之和
Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all un ...
- Maya 2015 中英文切换
我们在使用Maya软件的时候,有时候需要把语言在中英文之间切换,目前我感觉在不用插件的情况下,下面两种方法可以比较容易的做到: 方法一: 右键我的电脑属性,高级系统设置里面找到环境变量面板,然后新建一 ...