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使得目标类和各个切面完全松耦合,这样设计的系统架构更好,更有利于团队开发,代码复用

时间: 2024-10-06 21:07:08

spring02的相关文章

JAVAEE——spring02:使用注解配置spring、sts插件、junit整合测试和aop演示

一.使用注解配置spring 1.步骤 1.1 导包4+2+spring-aop 1.2 为主配置文件引入新的命名空间(约束) 1.3 开启使用注解代替配置文件 1.4 在类中使用注解完成配置 2.将对象注册到容器 //<bean name="user" class="cn.itcast.bean.User" /> //@Component("user") // @Service("user") // servic

spring-02

构造方法 Dept.java package cn.mldn.vo; import java.io.Serializable; @SuppressWarnings("serial") public class Dept implements Serializable { private Integer deptno ; private String dname ; private String loc ; public Dept(Integer deptno,String dname

Spring第二天——IOC注解操作与AOP概念

大致内容 spring的bean管理(注解实现) AOP原理 log4j介绍 spring整合web项目的演示 一.spring注解实现bean管理 注解: 代码中一些特殊的标记,使用注解也可以完成一些相关的功能(写法"@") 方法上.类上(详见基础加强) 使用注解创建对象,注入属性(完成day01相似的功能) 可以使用注解,但不可能完全替代xml配置文件 准备工作: 导入包:除了day01的6个核心jar包(当然包括日志的包) 再加上aop的那个jar包(注解功能在里面),也就是图中

(转)Spring 的 init-method 和 destory-method

背景:今天在项目中看到spring中bean在初始化和注销时候的方法定义,之前没有用过这种方式,在此记录下,方便后期查看! 关于在spring 容器初始化 bean 和销毁前所做的操作定义方式有三种: 第一种:通过@PostConstruct 和 @PreDestroy 方法 实现初始化和销毁bean之前进行的操作 第二种是:通过 在xml中定义init-method 和 destory-method方法 第三种是: 通过bean实现InitializingBean和 DisposableBea

Spring事务管理4-----声明式事务管理(2)

声明式事务管理  基于AspectJ的 XML 方式配置 通过对事务管理器TransactionManager配置通知(增强),然后再配置切点和切面,详细见applicationContext.xml配置文件 这种事务管理对业务层没有代码修改,在xml配置文件中也简化了设置,在真正开发中经常使用. dao层 /** * @author AT * 转账dao层 */ public interface AccountDao { /** * 转出钱 * @param outer * @param mo

Spring ioc 常用 详解

[TOC] Spring容器 配置对象时默认的单例的 可以设置bean的scope属性 singleton 单例模式,只会在IOC容器初始化的时候创建bean,并且只会创建一次 prototype 原型模式,在每次获取bean的时候才会创建bean,并且每次获取都会创建一个新的对象 session 每个会话共享一个bean request 每个请求共享一个bean 配置的方式 通过 属性名 对应 属性值 进行配置 通过类的构造进行配置 当一个javaBean中包含对像的属性时 可以通过(ref)

Spring05——Spring 如何实现事务管理

在此之前,我们已经了解了 Spring 相关的基础知识,今天将为给位带来,有关 Spring 事务代理的相关知识.关注我的公众号「Java面典」,每天 10:24 和你一起了解更多 Java 相关知识点. 事务管理方式 在 Spring 项目中,我们可以用通过四种方式实现事务管理,分别是 编程式事务管理.基于 TransactionProxyFactoryBean的声明式事务管理.基于 @Transactional 的声明式事务管理 和 基于Aspectj AOP配置事务.其实现方式如下: 编程