spring5框架尚硅谷学习笔记(三)

AOP (概念)
 
1 、什么是 AOP
1 )面向切面编程(方面),利用 AOP 可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
2 )通俗描述:不通过修改源代码方式,在主干功能里面添加新功能
3 )使用登录例子说明 AOP
 
 
AOP (底层原理)
 
1.创建UserDao实现类的代理对象、通过代理对象来增强类的方法
2.创建子类的代理对象,增强类的方法
 
1 AOP 底层使用动态代理
1 )有两种情况动态代理
第一种 有接口情况,使用 JDK 动态代理
创建接口实现类代理对象,增强类的方法
第二种 没有接口情况,使用 CGLIB 动态代理
创建子类的代理对象,增强类的方法
 

 

AOP JDK 动态代理)
 
1 、使用 JDK 动态代理,使用 Proxy 类里面的方法创建代理对象
1 )调用 newProxyInstance 方法 创建接口代理类的实现对象
方法有三个参数:
第一参数,类加载器
第二参数,增强方法所在的类,这个类实现的接口,支持多个接口
第三参数,实现这个接口 InvocationHandler ,创建代理对象,写增强的部分
 
2 、编写 JDK 动态代理代码
1 )创建接口,定义方法
public interface UserDao {
public int add( int a, int b);
public String update(String id);
}
2 )创建接口实现类,实现方法
public class UserDaoImpl implements UserDao {
@Override
public int add( int a, int b) {
return a+b;
}
@Override
public String update(String id) {
return id;
}
}
3 )使用 Proxy 类创建接口代理对象
//创建接口代理对象
public class JDKProxy {
    public static void main(String[] args) {
        Class[] interfaces = {UserDao.class};
//        //1.使用匿名内部类
//        Proxy.newProxyInstance(JDKProxy.class.getClassLoader(), interfaces,
//        new InvocationHandler() {
//             public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//                    return null;
//             }
//        });
        UserDaoImpl userDao = new UserDaoImpl();
        UserDao o =(UserDao) Proxy.newProxyInstance(JDKProxy.class.getClassLoader(), interfaces, new UserDaoProxy(userDao));
        int add = o.add(1, 2);
        System.out.println("result:"+add);
    }
}

class UserDaoProxy implements InvocationHandler{

    private Object obj;
    public UserDaoProxy(Object obj){
        this.obj=obj;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("方法执行之前执行:"+method.getName()+"参数:"+ Arrays.toString(args));
        //被增强的方法执行
        Object invoke = method.invoke(obj, args);
        System.out.println("方法执行之后执行:"+obj);
        return invoke;
    }
}
AOP (术语)
 
1 、连接点
2 、切入点
3 、通知(增强)
 
4 、切面
 
AOP 操作(准备工作)
 
1 Spring 框架一般都是基于 AspectJ 实现 AOP 操作
1 AspectJ 不是 Spring 组成部分,独立AOP 框架,一般把 AspectJ Spirng 框架一起使用,进行 AOP 操作
2 、基于 AspectJ 实现 AOP 操作
1 )基于 xml 配置文件实现
2 )基于注解方式实现(使用)
3 、在项目工程里面引入 AOP 相关依赖

4 、切入点表达式
1 )切入点表达式作用:知道对哪个类里面的哪个方法进行增强
2 )语法结构: execution([ 权限修饰符 ] [ 返回类型 ] [ 类全路径 ] [ 方法名称 ]([ 参数列表 ]) )
举例 1 :对 com.atguigu.dao.BookDao 类里面的 add 进行增强
execution(* com.atguigu.dao.BookDao.add(..))
举例 2 :对 com.atguigu.dao.BookDao 类里面的所有的方法进行增强
execution(* com.atguigu.dao.BookDao.* (..)) 举例 3 :对 com.atguigu.dao 包里面所有类,类里面所有方法进行增强
execution(* com.atguigu.dao.*.* (..))
AOP 操作( AspectJ 注解)
1 、创建类,在类里面定义方法
public class User {
public void add() {
System. out .println( "add......." );
}
}
2 、创建增强类(编写增强逻辑)
1 )在增强类里面,创建方法,让不同方法代表不同通知类型
//增强的类
public class UserProxy {
public void before() { //前置通知
System. out .println( "before......" );
}
}
3 、进行通知的配置
1 )在 spring 配置文件中,开启注解扫描
<? 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: context = "http://www.springframework.org/schema/context"
xmlns: aop = "http://www.springframework.org/schema/aop"
xsi :schemaLocation= "http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd" >
<!-- 开启注解扫描 -->
< context :component-scan base- package= "com.atguigu.spring5.aopanno" ></ context :component-scan >
2 )使用注解创建 User UserProxy 对象
3 )在增强类上面添加注解 @Aspect
//增强的类 @Component
@Aspect //生成代理对象
public class UserProxy {
4 )在 spring 配置文件中开启生成代理对象
<!-- 开启 Aspect 生成代理对象-->
< aop :aspectj-autoproxy ></ aop :aspectj-autoproxy >
4 、配置不同类型的通知
1 )在增强类的里面,在作为通知方法上面添加通知类型注解,使用切入点表达式配置
 
//增强的类
@Component
@Aspect //生成代理对象
public class UserProxy {
//前置通知
//@Before 注解表示作为前置通知
@Before (value = "execution(* com.atguigu.spring5.aopanno.User.add(..))" )
public void before() {
System. out .println( "before........." );
}
//后置通知(返回通知)
@AfterReturning (value = "execution(* com.atguigu.spring5.aopanno.User.add(..))" )
public void afterReturning() {
System. out .println( "afterReturning........." );
}
//最终通知
@After (value = "execution(* com.atguigu.spring5.aopanno.User.add(..))" )
public void after() {
System. out .println( "after........." );
}
//异常通知
@AfterThrowing (value = "execution(* com.atguigu.spring5.aopanno.User.add(..))" )
public void afterThrowing() {
System. out .println( "afterThrowing........." );
}
//环绕通知
@Around (value = "execution(* com.atguigu.spring5.aopanno.User.add(..))" )
public void around(ProceedingJoinPoint proceedingJoinPoint) throws
Throwable {
System. out .println( "环绕之前........." );
//被增强的方法执行
proceedingJoinPoint.proceed();
System. out .println( "环绕之后........." );
}
}
after:方法执行之后执行
afterReturning:方法返回之后再执行
afterThrowing:方法有异常时执行,且不在执行afterReturning。
5 、相同的切入点抽取
//相同切入点抽取
@Pointcut (value = "execution(* com.atguigu.spring5.aopanno.User.add(..))" )
public void pointdemo() {
}
//前置通知
//@Before 注解表示作为前置通知
@Before (value = "pointdemo()" )
public void before() {
System. out .println( "before........." );
}
 
6 、有多个增强类对同一个方法进行增强,设置增强类优先级
1 )在增强类上面添加注解 @Order( 数字类型值 ) ,数字类型值越小优先级越高
@Component
@Aspect
@Order ( 1 )
public class PersonProxy
7、完全使用注解开发
(1)创建配置类,不需要创建 xml 配置文件
@Configuration
@ComponentScan (basePackages = { "com.atguigu" })
@EnableAspectJAutoProxy (proxyTargetClass = true )
public class ConfigAop {
}
AOP 操作( AspectJ 配置文件)
 
1 、创建两个类,增强类和被增强类,创建方法
2 、在 spring 配置文件中创建两个类对象
<!--创建对象-->
< bean id= "book" class= "com.atguigu.spring5.aopxml.Book" ></ bean >
< bean id= "bookProxy" class= "com.atguigu.spring5.aopxml.BookProxy" ></ bean >
3 、在 spring 配置文件中配置切入点
<!--配置 aop 增强-->
< aop :config >
<!--切入点-->
< aop :pointcut id= "p" expression= "execution(* com.atguigu.spring5.aopxml.Book.buy(..))" />
<!--配置切面-->
< aop :aspect ref= "bookProxy" >
<!--增强作用在具体的方法上-->
< aop :before method= "before" pointcut-ref= "p" /> </ aop :aspect >
</ aop :config >

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值