Spring的入门学习笔记 (AOP概念及操作+AspectJ)
AOP概念
1.aop:面向切面(方面)编程,扩展功能不通过源代码实现
2.采用横向抽取机制,取代了传统的纵向继承重复代码
AOP原理
假设现有
public class User{ //添加用户方法(1) public void add(){ //添加逻辑(2)
//(3)
} }
我们需要扩展其功能:
正常需要在3处添加逻辑,但这种方式不好,需要经常修改代码
纵向抽取机制解决:
public class BaseUser{ //创建方法 public void writelog(){ //添加逻辑 } } public class User extends BaseUser{ public void add(){ //添加逻辑 //添加功能扩展 //调用父类方法 suer.writelog(); } }
但:如果父类方法名发生变化,子类调用方法也需要变化
横向抽取机制:
aop:底层使用动态代理的方式实现
第一种情况:
public interface Dao{ public void add(); } //使用动态代理的方式,创建接口实现类代理对象(实现和daoimpl平级的对象,但不是个真正对象,但可以实现和其相同的功能) public class DaoImpl implements Dao{ public void add(){ //添加逻辑 } }
第二种情况:
public class User{ public void add(){ } } //动态代理实现 创建User类的子类的代理对象 子类中调用父类方法完成增强(super) //使用cgllb动态代理,没有接口情况
AOP操作术语
public class User{ public void add(){} public void delete(){} public void update(){} public void findAll(){} }
切入点:类中的哪些方法可以被增强,这些方法就是连接点;如果只有update和add,则这实际增强方法为切入点
通知/增强:增强的逻辑,成为增强(前置/方法之前,后置/方法之后,异常/出现异常,最终/后置之后为最终,环绕增强/在方法之前和之后执行)
切面:把增强用于具体方法增强,过程为切面
在Spring里进行aop操作,使用aspectJ实现
AspectJ同Spring一起使用,但不属于Spring,一起进行aop操作
Spring2.0以后增加了对Aspectj的支持
使用aspectj实现aop实现的两种方式
1.基于aspectj的xml配置
2.基于aspectj的注解方式
Aop的操作准备
1.除基本的外,还有aop的相关jar包
2.创建spring核心配置文件,导入aop的约束
表达式配置切入点
1.切入点,实际增强切入点
2.常用表达式
1)execution(* cn.itcast.aop.Book.add(..))
2)execution(* cn.itcast.aop.Book.*(..))(
3)execution(* *.*(..))
4)execution(* save*(..))
xml配置:
<bean id="Book" class="cn.itcast.aop.Book"></bean> <bean id="MyBook" class="cn.itcast.aop.MyBook"></bean> <aop:config> <!--切入点> <aop:pointcut expression="execution(* cn.itcast.aop.Book.*(..))" id="pointcut1"> </aop:pointcut> <!--配置切面> <aop:aspect ref="MyBook"> <!--配置增强类型 menthod为增强类里面使用哪个方法为前置 ahter-returning menthod后写后置> <aop:before method="before1" pointcut-ref = "pointcut1"/> </aop:aspect> </aop:config>
另一部分:public class Book{ public void add( system.out.println("add......") }
} public class MyBook{ public void before1(){ system.out.println("前置增强......"); }
//环绕写法
public void around1(ProceedingJoinPoint proceedingJoinPoint) throw Throwable{
System.out.printLn("方法之前...");
//执行被增强的方法
ProceedingJoinPoint.proceed();
System.out.printLn("方法之后...");
}}
aspectj注解操作(更简单):
public class Book{ public void add(){ } } @Aspect public class MyBook{
@Before(value="execution(* 路径1.*(..))")
public void before1(){ } }
<!--创建对象--> <bean id ="book" class="路径1"></bean> <bean id ="book" class="路径2"></bean> <!--开启aop--> <aop:asceptj-autoproxy> </...>