Spring AOP

关于我断更一个半月这件事,原因很简单 我在考驾证哈哈哈哈,4.1改革之后 ,科一考三次才过正常么?好赖咱第三次过了,然后就练车 ,不是在练车就是在练车的路上~就是拿到了 一个科二一把过的好成绩,科三还没约上,等等吧~

最近在找实习,各种投简历哈,跪求个offer~~~

目录

简介

优点

Spring AOP

AOP术语

动态代理

JDK动态代理

CGLIG代理

 SpringAOP 实现代理

AspectJ

简介

基于XML的声明式AspectJ

代码实现

基于注解的声明式AspectJ

 代码实现

 小结


简介

先介绍两个两个概念

AOP:面向切面编程(横向抽取)

OOP:面向对象编程(纵向抽取)

对于面向对象就是我们之前在javaSE接触的一种编程方式,AOP是对OOP的补充而不是替代,从字面意思理解,“切面”就是意味着横向抽取,简而言之, 把我们之前写过的代码中的重复率比较大的代码抽取出来,封装到切面中,然后在需要的地方进行植入。(就是说把总能用到的东西提取出来,哪里需要就在哪里引入,多方便~)

举个栗子(针对于 不理解“横向抽取”和“纵向抽取”)

OOP的纵向抽取 

有三个实体类 Teacher(name,age,gender),Student(name,age,gender),Woker(name,age,gender) 他们都有相同的属性(name,age,gender),我们一个一个的 去写肯定是可以的,但是没有必要,如果属性特别多,那肯定会很难过,在javase里面的建议是——继承

创建一个父类(Person)包含这几个实体类共有的属性(抽取出来),然后我们的实体类直接去继承Person,就都可以拥有这些属性啦,简单方便快捷!

AOP的横向抽取

一个UserService里面有很多方法,addUser();updateUser();deleteUser()……来进行对数据的核心操作,在进行这些操作之前可能需要“开启事务”,操作之后“关闭事务”,在每个方法里都需要执行类似于“开启、关闭事务”的操作,有什么方法是解决这个大量重复操作的呢,不能像之前一样创建一个父类纵向抽取,因为这个代码是横向的,那么我们可以把这些代码拿出来单独放到一个类里面,然后想要使用的地方植入就好啦(具体实现可以看后面的“代码”部分)

优点

使开发人员在编写业务逻辑时可以专心于核心业务,而不用过多的关注于其他业务逻辑的实现,这不但提高了开发效率,而且增强了代码的可维护性。

目前最流行的AOP框架由两个,分别是Spring AOP和AspectJ

Spring AOP

AOP术语

 

Aspect(切面) 封装通知的类
Joinpoint(连接点) 程序执行中的某个阶段点,在Spring AOP中,指的是对象中的方法
Pointcut(切入点) 需要增强的方法
Advice(通知/增强处理) 需要增强的代码
Target Object(目标对象) 被通知的对象,被增强的对象
Proxy(代理) 将通知应用到目标对象之后,创建的代理对象
Weaving(织入) 将切面代码插入到目标对象上,从而生成代理对象的过程

 

动态代理

Spring中AOP是通过代理的方式来实现的,可以是JDK动态代理,也可以是CGLIB代理

JDK动态代理

导入jar包

         <!--AOP依赖 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>5.3.6</version>
        </dependency>
        <dependency>
            <groupId>aopalliance</groupId>
            <artifactId>aopalliance</artifactId>
            <version>1.0</version>
        </dependency>

代码实现

1)创建接口

package com.cz.jdk;

public interface UserDao {
    void addUser();
}

2)创建接口实现类

package com.cz.jdk;

public class UserDaoImpl implements UserDao{
    @Override
    public void addUser() {
        //模拟权限检查
        System.out.println("user添加成功!");
        //模拟日志记录
    }
}

3)创建切面

package com.cz.jdk;

public class MyAspect {
    public void check(){
        System.out.println("权限检查...");
    }
    public void log(){
        System.out.println("日志记录....");
    }
}

4)创建代理类

package com.cz.jdk;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class JdkProxy {
    public Object createProxy(Object target){
        //类加载器
        ClassLoader classLoader = MyTest.class.getClassLoader();
        //实现接口
        Class<?>[] interfaces = target.getClass().getInterfaces();
        Object o = Proxy.newProxyInstance(classLoader, interfaces, new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                MyAspect myAspect = new MyAspect();
                myAspect.check();
                Object o = method.invoke(target, args);
                myAspect.log();
                return o;
            }
        });
        return o;
    }
}

5)测试

        //目标对象
        UserDao userDao = new UserDaoImpl();
        //类加载器
        ClassLoader classLoader = MyTest.class.getClassLoader();
        //实现接口
        Class<?>[] interfaces = userDao.getClass()
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值