SpringAOP

SpringAOP

优点:

  • 解藕
  • 更好的代码复用

如何使用

  • 创建maven项目,导入依赖
<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aop</artifactId>
        <version>5.0.11.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aspects</artifactId>
        <version>5.0.11.RELEASE</version>
    </dependency>
</dependencies>
  • 创建一个计算器接口,定义加减乘除方法

    package org.csu.utils;
    
    public interface Cal {
        public int add(int num1,int num2);
        public int sub(int num1,int num2);
        public int mul(int num1,int num2);
        public int div(int num1,int num2);
    }
  • 创建接口的实现类方法

    package org.csu.utils.impl;
    
    import org.csu.utils.Cal;
    
    public class CalImpl implements Cal {
    
        public int add(int num1, int num2) {
            System.out.println("add方法的参数是["+ num1+","+num2+"]");
            int result = num1 + num2;
            System.out.println("add方法的结果是["+ result+"]");
            return result;
        }
    
        public int sub(int num1, int num2) {
            System.out.println("sub方法的参数是["+ num1+","+num2+"]");
    
            int result = num1 - num2;
            System.out.println("sub方法的结果是["+ result+"]");
    
            return result;
        }
    
        public int mul(int num1, int num2) {
            System.out.println("mul方法的参数是["+ num1+","+num2+"]");
    
            int result = num1 * num2;
            System.out.println("mul方法的结果是["+ result+"]");
    
            return result;
        }
    
        public int div(int num1, int num2) {
            System.out.println("div方法的参数是["+ num1+","+num2+"]");
            int result = num1 / num2;
            System.out.println("div方法的结果是["+ result+"]");
    
            return result;
        }
    }

上述代码中,日志信息与业务逻辑的耦合度很高,不利于系统的维护,使用AOP可以优化。可以通过动态***来实现AOP

给业务逻辑找一个***,打印日志信息的工作交给***来做,这样的话业务代码就只需要关注自身的业务即可。

package org.csu.utils;

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

public class MyInvokationHandler implements InvocationHandler {
   //接受委托对象
    private Object object = null;
    //返回***对象
    public Object bind(Object object){
        this.object = object;
        return Proxy.newProxyInstance(object.getClass().getClassLoader(),object.getClass().getInterfaces(),this);
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println(method.getName() + "的参数是"+ Arrays.toString(args));
        Object result = method.invoke(this.object,args);
        System.out.println(method.getName()+"的结果是"+result);
        return result;
    }
}

以上通过动态***的方法实现AOP的过程,复杂且不好理解。Spring对AOP进行了封装,可以用面向对象的方法来实现AOP。

Spring不用创建InvocationHandler,只需要创建一个切面对象,将所有的非业务代码放在切面对象中完成即可。Spring会根据切面类以及目标类生成一个***对象

package org.csu.utils.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

import java.util.Arrays;

@Component
@Aspect
public class LoggerAspect {
    @Before("execution(public int org.csu.utils.impl.CalImpl.*(..))")
    public void before(JoinPoint joinPoint){
        //获取方法名
        String name = joinPoint.getSignature().getName();
        //获取参数
        String args = Arrays.toString(joinPoint.getArgs());
        System.out.println(name +"的aop参数是"+args);


    }
}

两个注解:

  • @Aspect : 表明该类是切面类
  • @Component :把该类的对象注入到IOC容器中

spring.xml中配置aop

<?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-2.5.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">

    <!-- 创建 SimpleDateFormat 实例并对这个实例进行实例化-->
<!--    自动扫描-->
    <context:component-scan base-package="org.csu"></context:component-scan>
<!--使得asect注解生效,为目标类自动生成***对象-->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

</beans>

context:component-scan 将 org.csu包中所有类进行扫描,如果该类同时添加了 @Component,则将该类扫描到ioc容器中,让ioc管理他的对象

aop:aspectj-autoproxy 让spring结合切面类与目标类自动生成***对象

调用aop

package org.csu.utils.test;

import org.csu.utils.Cal;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class test2 {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-aop.xml");
        //获取***对象
        Cal proxy =(Cal) applicationContext.getBean("calImpl");
        proxy.add(6,7);
    }
}
全部评论

相关推荐

点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
正在热议
更多
# 春招至今,你的战绩如何? #
9937次浏览 92人参与
# 你的实习产出是真实的还是包装的? #
1793次浏览 41人参与
# MiniMax求职进展汇总 #
23895次浏览 308人参与
# 军工所铁饭碗 vs 互联网高薪资,你会选谁 #
7494次浏览 43人参与
# 简历第一个项目做什么 #
31591次浏览 332人参与
# 重来一次,我还会选择这个专业吗 #
433398次浏览 3926人参与
# 巨人网络春招 #
11307次浏览 223人参与
# 当下环境,你会继续卷互联网,还是看其他行业机会 #
187025次浏览 1122人参与
# 牛客AI文生图 #
21414次浏览 238人参与
# 不考虑薪资和职业,你最想做什么工作呢? #
152310次浏览 887人参与
# 研究所笔面经互助 #
118882次浏览 577人参与
# 简历中的项目经历要怎么写? #
310120次浏览 4197人参与
# AI时代,哪些岗位最容易被淘汰 #
63489次浏览 806人参与
# 面试紧张时你会有什么表现? #
30490次浏览 188人参与
# 你今年的平均薪资是多少? #
213034次浏览 1039人参与
# 你怎么看待AI面试 #
179917次浏览 1237人参与
# 高学历就一定能找到好工作吗? #
64317次浏览 620人参与
# 你最满意的offer薪资是哪家公司? #
76452次浏览 374人参与
# 我的求职精神状态 #
448008次浏览 3129人参与
# 正在春招的你,也参与了去年秋招吗? #
363299次浏览 2637人参与
# 腾讯音乐求职进展汇总 #
160600次浏览 1111人参与
# 校招笔试 #
470578次浏览 2964人参与
牛客网
牛客网在线编程
牛客网题解
牛客企业服务