精华内容
下载资源
问答
  • Java基于自定义注解的面向切面的实现
    2021-03-11 16:54:10

    1、写一个切面

    @Aspect
    @Component
    public class LogInfoAspect {
    
        @Pointcut(value = "@annotation(com.main.entity.annotation.LogInfo)")
        public void LogInfoAspect(){
    
        }
        // 在这里定义前置切面
        @Before("LogInfoAspect()")
        public void beforeMethod(JoinPoint joinPoint) {
    
            // 这里执行保存日志的动作
            System.out.println("before .......");
            //得到被切方法的参数
            System.out.println(joinPoint.getArgs()[0]);
        }
    }

    2、写一个注解

    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Target(ElementType.METHOD)
    public @interface LogInfo {
        boolean value() default true;
    }

    3、controller的引用

        @LogInfo
        @RequestMapping(value = "/trrtt")
        public String trrtt(HttpServletRequest request, Model model) {
          return “success”
        }

     

    更多相关内容
  • 十、使用注解定义切面

    千次阅读 2021-03-09 06:57:51
    一、本课目标掌握使用注解实现AOP的方法二、使用注解定义切面2.1简介AspectJ面向切面的框架,它扩展了Java语言,定义了AOP语法,能够在编译期提供代码的织入。@AspectJAspectJ5新增的功能,使用JDK5.0注解技术和正规...

    一、本课目标

    掌握使用注解实现AOP的方法

    二、使用注解定义切面

    2.1简介

    AspectJ

    面向切面的框架,它扩展了Java语言,定义了AOP语法,能够在编译期提供代码的织入。

    @AspectJ

    AspectJ5新增的功能,使用JDK5.0注解技术和正规的AspectJ切点表达式语言描述切面(所以在使用@AspectJ的时候,要保证所用的JDK是5.0或者以上的版本)

    Spring通过集成AspectJ实现了以注解的方式定义增强类,大大减少了配置文件中的工作量

    利用轻量级的字节码处理框架asm处理@AspectJ中所描述的方法参数名

    2.2示例

    需求:使用注解来实现日志切面

    分析:

    1、使用注解定义前置增强和后置增强实现日志功能

    2、编写Spring配置文件,完成切面织入

    1329dfcb5c15?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

    image.png

    实体类:

    package entity;

    /**

    * 用户实体类

    */

    public class User implements java.io.Serializable {

    private Integer id; // 用户ID

    private String username; // 用户名

    private String password; // 密码

    private String email; // 电子邮件

    // getter & setter

    public Integer getId() {

    return id;

    }

    public void setId(Integer id) {

    this.id = id;

    }

    public String getUsername() {

    return username;

    }

    public void setUsername(String username) {

    this.username = username;

    }

    public String getPassword() {

    return password;

    }

    public void setPassword(String password) {

    this.password = password;

    }

    public String getEmail() {

    return email;

    }

    public void setEmail(String email) {

    this.email = email;

    }

    }

    增强类:

    package aop;

    import java.util.Arrays;

    import org.apache.log4j.Logger;

    import org.aspectj.lang.JoinPoint;

    import org.aspectj.lang.annotation.Aspect;

    import org.aspectj.lang.annotation.Before;

    /**

    * 增强处理类

    * @author Administrator

    *

    */

    @Aspect

    public class UserServiceLogger {

    private static Logger log = Logger.getLogger(UserServiceLogger.class);

    @Before("execution(* service.UserService.*(..))")

    public void before(JoinPoint jp) {

    log.info("调用" + jp.getTarget() + "的" +

    jp.getSignature() + "方法,方法参数" +

    Arrays.toString(jp.getArgs()));

    }

    public void afterReturning(JoinPoint jp, Object result) {

    log.info("调用" + jp.getTarget() + "的" +

    jp.getSignature() + "方法,方法返回值" +

    result);

    }

    }

    dao层:

    package dao;

    import entity.User;

    /**

    * 增加DAO接口,定义了所需的持久化方法

    */

    public interface UserDao {

    public void save(User user);

    }

    package dao.impl;

    import org.springframework.stereotype.Repository;

    import dao.UserDao;

    import entity.User;

    /**

    * 用户DAO类,实现UserDao接口,负责User类的持久化操作

    */

    @Repository("userDao")

    public class UserDaoImpl implements UserDao {

    public void save(User user) {

    // 这里并未实现完整的数据库操作,仅为说明问题

    System.out.println("保存用户信息到数据库");

    }

    }

    service层:

    package service;

    import entity.User;

    /**

    * 用户业务接口,定义了所需的业务方法

    */

    public interface UserService {

    public void addNewUser(User user);

    }

    package service.impl;

    import org.springframework.beans.factory.annotation.Autowired;

    import org.springframework.beans.factory.annotation.Qualifier;

    import org.springframework.stereotype.Service;

    import service.UserService;

    import dao.UserDao;

    import entity.User;

    /**

    * 用户业务类,实现对User功能的业务管理

    */

    @Service("userService")

    public class UserServiceImpl implements UserService {

    // 声明接口类型的引用,和具体实现类解耦合

    private UserDao dao;

    /* // 无参构造

    public UserServiceImpl() {

    }*/

    @Autowired

    // 指定装配的bean的名称

    public void setDao(@Qualifier("userDao")UserDao dao) {

    this.dao = dao;

    }

    /* // 用于为dao属性赋值的构造方法

    public UserServiceImpl(UserDao dao) {

    this.dao = dao;

    }*/

    public void addNewUser(User user) {

    // 调用用户DAO的方法保存用户信息

    dao.save(user);

    }

    }

    配置文件:

    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-3.2.xsd

    http://www.springframework.org/schema/context

    http://www.springframework.org/schema/context/spring-context-3.2.xsd

    http://www.springframework.org/schema/aop

    http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">

    测试类:

    package test;

    import org.springframework.context.ApplicationContext;

    import org.springframework.context.support.ClassPathXmlApplicationContext;

    import service.UserService;

    import entity.User;

    public class Test {

    @org.junit.Test

    public void test() {

    // 使用ApplicationContext接口的实现类ClassPathXmlApplicationContext加载Spring配置文件

    ApplicationContext ctx = new ClassPathXmlApplicationContext(

    "applicationContext.xml");

    // 通过ApplicationContext接口的getBean()方法获取id或name为userService的Bean实例

    UserService service = (UserService) ctx.getBean("userService");

    User user = new User();

    user.setId(1);

    user.setUsername("test");

    user.setPassword("123456");

    user.setEmail("test@xxx.com");

    service.addNewUser(user);

    }

    }

    运行结果:

    1329dfcb5c15?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

    image.png

    增加后置增强:

    package aop;

    import java.util.Arrays;

    import org.apache.log4j.Logger;

    import org.aspectj.lang.JoinPoint;

    import org.aspectj.lang.annotation.AfterReturning;

    import org.aspectj.lang.annotation.Aspect;

    import org.aspectj.lang.annotation.Before;

    /**

    * 增强处理类

    * @author Administrator

    *

    */

    @Aspect

    public class UserServiceLogger {

    private static Logger log = Logger.getLogger(UserServiceLogger.class);

    @Before("execution(* service.UserService.*(..))")

    public void before(JoinPoint jp) {

    log.info("调用" + jp.getTarget() + "的" +

    jp.getSignature() + "方法,方法参数" +

    Arrays.toString(jp.getArgs()));

    }

    @AfterReturning(pointcut="execution(* service.UserService.*(..))",

    returning="result")

    public void afterReturning(JoinPoint jp, Object result) {

    log.info("调用" + jp.getTarget() + "的" +

    jp.getSignature() + "方法,方法返回值" +

    result);

    }

    }

    运行结果:

    1329dfcb5c15?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

    image.png

    注:有时候同一个切入点要在很多地方用到,这时候我们要进行统一的定义,以方便我们的重用和维护。

    代码如下:

    package aop;

    import java.util.Arrays;

    import org.apache.log4j.Logger;

    import org.aspectj.lang.JoinPoint;

    import org.aspectj.lang.annotation.AfterReturning;

    import org.aspectj.lang.annotation.Aspect;

    import org.aspectj.lang.annotation.Before;

    import org.aspectj.lang.annotation.Pointcut;

    /**

    * 增强处理类

    * @author Administrator

    *

    */

    @Aspect

    public class UserServiceLogger {

    private static Logger log = Logger.getLogger(UserServiceLogger.class);

    // 统一定义切入点,并定义该切入点的方法名

    @Pointcut("execution(* service.UserService.*(..))")

    public void pointcut() {}

    @Before("pointcut()")

    public void before(JoinPoint jp) {

    log.info("调用" + jp.getTarget() + "的" +

    jp.getSignature() + "方法,方法参数" +

    Arrays.toString(jp.getArgs()));

    }

    @AfterReturning(pointcut="pointcut()",

    returning="result")

    public void afterReturning(JoinPoint jp, Object result) {

    log.info("调用" + jp.getTarget() + "的" +

    jp.getSignature() + "方法,方法返回值" +

    result);

    }

    }

    三、使用注解丁义珍增强

    需求说明:使用注解来定义异常抛出增强

    分析:

    使用@AfterThrowing注解定义异常抛出增强

    增强类:

    package aop;

    import org.apache.log4j.Logger;

    import org.aspectj.lang.JoinPoint;

    import org.aspectj.lang.annotation.AfterThrowing;

    import org.aspectj.lang.annotation.Aspect;

    /**

    * 定义包含增强方法的JavaBean

    */

    @Aspect

    public class ErrorLogger {

    private static final Logger log = Logger.getLogger(ErrorLogger.class);

    @AfterThrowing(pointcut="execution(* service.UserService.*(..))",

    throwing="e")

    public void afterThrowing(JoinPoint jp, RuntimeException e) {

    log.error(jp.getSignature().getName() + " 方法发生异常:" + e);

    }

    }

    dao层

    package dao.impl;

    import org.springframework.stereotype.Repository;

    import dao.UserDao;

    import entity.User;

    /**

    * 用户DAO类,实现UserDao接口,负责User类的持久化操作

    */

    @Repository("userDao")

    public class UserDaoImpl implements UserDao {

    public void save(User user) {

    // 这里并未实现完整的数据库操作,仅为说明问题

    System.out.println("保存用户信息到数据库");

    throw new RuntimeException("为测试程序运行效果抛出的异常");

    }

    }

    配置文件:

    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-3.2.xsd

    http://www.springframework.org/schema/context

    http://www.springframework.org/schema/context/spring-context-3.2.xsd

    http://www.springframework.org/schema/aop

    http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">

    运行结果:

    1329dfcb5c15?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

    image.png

    四、使用注解定义最终增强

    需求:使用注解来定义最终增强

    分析:使用@After注解定义最终增强

    增强类:

    package aop;

    import org.apache.log4j.Logger;

    import org.aspectj.lang.JoinPoint;

    import org.aspectj.lang.annotation.After;

    import org.aspectj.lang.annotation.Aspect;

    @Aspect

    public class AfterLogger {

    private static Logger log = Logger.getLogger(AfterLogger.class);

    @After("execution(* service.UserService.*(..))")

    public void after(JoinPoint jp) {

    log.info(jp.getSignature().getName() + "方法结束了");

    }

    }

    配置文件:

    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-3.2.xsd

    http://www.springframework.org/schema/context

    http://www.springframework.org/schema/context/spring-context-3.2.xsd

    http://www.springframework.org/schema/aop

    http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">

    运行结果:

    1329dfcb5c15?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

    image.png

    五、使用注解定义环绕增强

    需求说明:使用注解来定义环绕增强

    分析:使用@Around注解定义环绕增强

    增强类:

    package aop;

    import java.util.Arrays;

    import org.apache.log4j.Logger;

    import org.aspectj.lang.JoinPoint;

    import org.aspectj.lang.ProceedingJoinPoint;

    import org.aspectj.lang.annotation.Around;

    import org.aspectj.lang.annotation.Aspect;

    @Aspect

    public class AroundLogger {

    private static Logger log = Logger.getLogger(AroundLogger.class);

    /**

    * 可以通过修改这个方法的返回值来修改目标方法的返回值

    * @param jp

    * @return

    * @throws Throwable

    */

    @Around("execution(* service.UserService.*(..))")

    public Object aroundLogger(ProceedingJoinPoint jp ) throws Throwable {

    log.info("调用" + jp.getTarget() + "的" +

    jp.getSignature() + "方法,方法参数" +

    Arrays.toString(jp.getArgs()));

    Object result;

    try {

    result = jp.proceed();

    log.info("调用" + jp.getTarget() + "的" +

    jp.getSignature() + "方法,方法返回值" +

    result);

    return result;

    } catch (Throwable e) {

    log.error(jp.getSignature().getName() + " 方法发生异常:" + e);

    throw e;

    }finally {

    log.info(jp.getSignature().getName() + " 方法结束执行。");

    }

    }

    }

    配置文件:

    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-3.2.xsd

    http://www.springframework.org/schema/context

    http://www.springframework.org/schema/context/spring-context-3.2.xsd

    http://www.springframework.org/schema/aop

    http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">

    运行结果:

    1329dfcb5c15?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

    image.png

    六、小结

    1329dfcb5c15?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

    image.png

    1329dfcb5c15?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

    image.png

    展开全文
  • 自定义一个注解并实现注解返回后处理逻辑功能 自定义一个注解 @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface CommunityOperation { /** * 主键 */ String ...

    自定义一个注解并实现注解返回后处理逻辑功能

    自定义一个注解

    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface CommunityOperation {
    
        /**
         * 主键
         */
        String id() default "id";
    
        /**
         * 类型
         */
        ContentTypeEnum type();
    
        /**
         * 类型为空则使用typeName获取
         */
        String typeName() default "type";
    }
    

    JDK的元注解主要有@Target,@Retention,@Document,@Inherited用来修饰注解
    @Target:表示java可以应用的元素类型

    ElementType.TYPE:应用于类、接口(包括注解类型)、枚举
    ElementType.FIELD:应用于属性(包括枚举中的常量)
    ElementType.METHOD:应用于方法
    ElementType.PARAMETER:应用于方法的形参
    ElementType.CONSTRUCTOR:应用于构造函数
    ElementType.LOCAL_VARIABLE:应用于局部变量
    ElementType.ANNOTATION_TYPE:应用于注解类型
    ElementType.PACKAGE:应用于包
    ElementType.TYPE_PARAMETER:1.8版本新增,应用于类型变量)
    ElementType.TYPE_USE:1.8版本新增,应用于任何使用类型的语句中(例如声明语句、泛型和强制转换语句中的类型)

    @Retention:表明该注解的生命周期

    RetentionPolicy.SOURCE:编译时被丢弃,不包含在类文件中
    RetentionPolicy.CLASS:JVM加载时被丢弃,包含在类文件中,默认值
    RetentionPolicy.RUNTIME:JVM 加载,包含在类文件中,在运行时可以被获取到

    @Document:表明该注解标记的元素可以被Javadoc 或类似的工具文档化
    @Inherited:表明使用了@Inherited注解的注解,所标记的类的子类也会拥有这个注解

    增加切面处理注解

    @AfterReturning

    import com.alibaba.fastjson.JSONObject;
    import lombok.extern.slf4j.Slf4j;
    import org.apache.commons.lang3.StringUtils;
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.annotation.AfterReturning;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Pointcut;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Scope;
    import org.springframework.stereotype.Component;
    
    @Aspect
    @Scope
    @Component
    @Slf4j
    public class CommunityOperationAspect {
    
        private ContentSendMsgFactory contentSendMsgFactory;
    
        @Pointcut(value = "@annotation(com.xxxx.xxx.xxxxxx.annoation.CommunityOperation)")
        public void activitySendMessage() {}
    
        @AfterReturning(value = "activitySendMessage()&&@annotation(communityOperation)",returning = "result")
        public Object beforeRequestIdVerify(JoinPoint joinPoint, Object result, CommunityOperation communityOperation) {
            try {
                JSONObject jsonObject=JSONObject.parseObject(JSONObject.toJSONString(result));
                if(jsonObject.getIntValue("code")!= DefaultHttpResultStatus.SUCCESS.getCode()){
                    return result;
                }
                String id=StringUtils.EMPTY;
                Integer code=communityOperation.type().getCode();
                if(joinPoint.getArgs()[0] instanceof String){
                    id=String.valueOf(joinPoint.getArgs()[0]);
                }else{
                    JSONObject params=JSONObject.parseObject(JSONObject.toJSONString(joinPoint.getArgs()[0]));
                    id=params.getString(communityOperation.id());
                    if(communityOperation.type().getCode()==null){
                        code=params.getInteger(communityOperation.typeName());
                    }
                }
                if(StringUtils.isEmpty(id)){
                    log.info("活动或评论发送消息到es未传ID");
                }
                contentSendMsgFactory.send(Long.valueOf(id),code);
            } catch (Throwable throwable) {
                log.error("统计社区用户失败{}",throwable);
            }
            return result;
        }
    
        @Autowired
        public void setContentSendMsgFactory(ContentSendMsgFactory contentSendMsgFactory) {
            this.contentSendMsgFactory = contentSendMsgFactory;
        }
    }
    

    Around

        @Around("activitySendMessage()&&@annotation(communityOperation)")
        public Object beforeRequestIdVerify(ProceedingJoinPoint joinPoint, CommunityOperation communityOperation) {
            Object result = null;
            try {
                result = joinPoint.proceed();
                JSONObject jsonObject=JSONObject.parseObject(JSONObject.toJSONString(result));
                if(jsonObject.getIntValue("code")== DefaultHttpResultStatus.SUCCESS.getCode()){
                    JSONObject params=JSONObject.parseObject(JSONObject.toJSONString(joinPoint.getArgs()[0]));
                    Integer code=communityOperation.type().getCode();
                    if(communityOperation.type().getCode()==null){
                        code=params.getInteger(communityOperation.typeName());
                    }
                    if(StringUtils.isEmpty(params.getString(communityOperation.id()))){
                        log.info("活动或评论发送消息到es未传ID");
                    }
                    contentSendMsgFactory.send(params.getLong(communityOperation.id()),code);
                }
            } catch (Throwable throwable) {
                log.error("统计社区用户失败{}",throwable);
            }
            return result;
        }
    

    @Before

    用于打印请求类名、方法名、请求参数

        @Before(value = "pointcutController()")
        public void before(JoinPoint joinPoint) {
            String className = joinPoint.getTarget().getClass().getName();
            String methodName = joinPoint.getSignature().getName();
            Object[] args = joinPoint.getArgs();
            List<Object> logArgs = streamOf(args)
                    .filter(arg -> (!(arg instanceof HttpServletRequest) && !(arg instanceof HttpServletResponse))&& (arg instanceof MultipartHttpServletRequest))
                    .collect(Collectors.toList());
            String argsJson = JSON.toJSONString(logArgs);
            String beforeLog = String.format("开始调用%s.%s,参数为:%s", className, methodName, argsJson);
            log.info(beforeLog);
        }
    

    使用

        @CommunityOperation(id="id",type= ContentTypeEnum.ACTIVITY)
        @PostMapping("/v1/publish")
        public HttpResult<Boolean> publish(@NotNull @RequestBody final ActivityRequestBean activityRequestBean) {
            
            return DefaultHttpResultFactory.fail("发布/取消失败。", Boolean.FALSE);
        }
    
    展开全文
  • JAVA实现简单的切面注解

    万次阅读 2019-08-22 00:31:07
    背景 今天在分析同事遇到一个springboot的注解和方法锁一起用而导致的问题(@...本文介绍java中其中一种(InvocationHandler)利用动态代理的方式实现的代理的方法,从而类似的机制我们推测出spring的切面...

    背景

    今天在分析同事遇到一个springboot的注解和方法锁一起用而导致的问题(@Transaction和synchronized用在同一个方法中由于事务先于锁进入后于锁释放而可能引发的数据问题)中而突然思考到spring的Aspect是怎么样的执行顺序,本文介绍java中其中一种(InvocationHandler)利用动态代理的方式实现的代理的方法,从而类似的机制我们推测出spring的切面其实也是在代理类中执行了切面的函数并在invoke之前或者之后去执行定义的点,而之所以能够自动扫描切面应该是类似spring rabbitmq的实现扫面一遍所有的component bean获取所有的注解然后执行,后续再仔细分析Aspect的实现,本文我们尝试实现aspect注解从而实现捕获函数执行前参数和执行后结果并打印出来

    代码

    package com.oujiangping.leetcode;
    
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    
    @Retention(RetentionPolicy.RUNTIME)
    public @interface aspect {
    }
    
    package com.oujiangping.leetcode;
    
    @aspect
    public interface TestAspect {
        public String test(String sr);
    }
    
    
    package com.oujiangping.leetcode;
    
    @aspect
    public class TestAspectImpl implements TestAspect {
        @Override
        public String test(String sr) {
            System.out.println("run TestAspectImpl.test " + sr);
            return sr;
        }
    }
    
    
    package com.oujiangping.leetcode;
    
    @aspect
    public class TestAspectImplA implements TestAspect {
        @Override
        public String test(String sr) {
            System.out.println("run TestAspectImplA.test " + sr);
            return sr;
        }
    }
    
    
    package com.oujiangping.leetcode;
    package com.oujiangping.leetcode;
    
    import java.lang.reflect.Field;
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    public class MyAspect implements InvocationHandler {
        Object instance;
    
        public Object aspect(Object instance) {
            this.instance = instance;
            return Proxy.newProxyInstance(instance.getClass().getClassLoader(), instance.getClass().getInterfaces(),this);
        }
    
        public void befor(Method method, Object[] args) {
            System.out.println("~~~~ befor: " + method.getName() + " " + args);
        }
    
        public void after(Object object) {
            System.out.println("~~~~ after: " + object);
        }
    
        public static void init() {
            Field[] fields= MyAspect.class.getDeclaredFields();
    
            for(int i=0;i<fields.length;i++){
                MyAspect myAspect = new MyAspect();
                aspect aspects = fields[i].getType().getAnnotation(aspect.class);
                if(aspects != null) {
                    fields[i].setAccessible(true);
                    try {
                        fields[i].set(myAspect, new MyAspect().aspect(fields[i].get(myAspect)));
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            Object result=null;
            befor(method, args);
            result = method.invoke(instance, args);
            after(result);
            return null;
        }
    
        public static TestAspect testAspect = new TestAspectImpl();
        public static TestAspect testAspectA = new TestAspectImplA();;
    
        public static void main(String []args) {
            init();
            testAspect.test("I'm TestAspectImpl");
            testAspectA.test("I'm TestAspectImplA");
        }
    }
    
    
    
    结果:
    ~~~~ befor: test [Ljava.lang.Object;@49476842
    run TestAspectImpl.test I'm TestAspectImpl
    ~~~~ after: I'm TestAspectImpl
    ~~~~ befor: test [Ljava.lang.Object;@78308db1
    run TestAspectImplA.test I'm TestAspectImplA
    ~~~~ after: I'm TestAspectImplA
    
    

    总结

    展开全文
  • java通过自定义注解实现切面记录操作日志自定义注解java.lang.annotation为开发者提供的元注解日志自定义注解实例日志切面实现在业务逻辑中使用自定义注解记录操作日志 自定义注解 java.lang.annotation为开发者提供...
  • Java-切面注解拦截器

    2020-05-08 16:59:16
    创建切面类,启用注解@Aspect、@Component、@Order(-99);通过@Pointcut("@annotation(具体注解类路径)")指定注解切入点;最后通过环绕通知(@Around(“pointCut()”))实现拦截效果,在此方法里进行判断,最终通过...
  • java 切面实现记录操作日志
  • 首先定义注解类 import java.lang.annotation.*; /** * @description: 保存或者修改字典权限判断注解 * @fileName: CommDictValidateAspect.java * @author: Sure * @createAt: 2021/12/13/013 16:14 * @updateBy: ...
  • 这是配套代码,如果看描述看不懂可以直接下载代码,惊醒研究,如有什么不合适的地方或者说修改的地方,可以提醒我,我到时候回一一修正以及完善
  • Java Springboot切面+注解实现数据脱敏1. 业务概述2. 设计编码2.1 脱敏类型枚举2.2 脱敏注解2.3 脱敏工具类2.4 统一拦截器2.5 统一结果集2.6 用户实体类2.7 用户控制类3. 实现验证 1. 业务概述 随着互联网发展日益...
  • 自定义缓存切面注解 1:展示效果 1.1: 成功保存到redis效果 第一次Redis没有值,所以保存查询了数据库。 1.2:第二次请求 2.1:前置条件 技术栈需要会简单的redis存、取、删和SpringAop即可 2.2: 安装redis ...
  • 一、背景需求: 数据类型特别多,需要实现对数据的操作是增删改查哪一种,如果每一个都进行...@Retention元注解的作用就是负责注解其他注解 @Target说明了Annotation所修饰的对象范围:Annotation可被用于 pack...
  • 学习目的:学会使用注解进行面向切面编程(AOP),实现在面向切面编程(AOP)中,使用XML配置完成的操作。Part 1修改cn.vaefun.dao.UserServiceImpl.java,在类上添加Component注解,告诉spring这是一个bean,并命名为...
  • 博主的问题是 用this无法生效切面 public class ServiceImpl implements Service { @Override public T getAssetDetail() { xxxxxx; } @Override @TranslateRemoteField public T ...
  • java面向切面日志处理

    2021-05-06 07:34:05
    1、注解Log类 package org.monitor.annotation; import org.monitor.enums.BusinessType; import org.monitor.enums.OperatorType; import java.lang.annotation.Documented; import java.lang.annotation....
  • 写代码时会遇到一些有些重复机械的工作, 这个时候就可以运用切面技术来帮我们节约时间 本文介绍如何使用自定义注解增强方法, 实现自动完成重复的工作(还可以通过直接扫描包路径增强所有方法, 或者根据方法名, 入参等...
  • spring AOP注解方式下不进切面方法

    千次阅读 2021-03-09 20:27:08
    最近写spring aop切面的时候,在一些方法上加了切点,然后在切面中添加对应切点的方法,但是有些切点的方法不执行,有的执行。下面是两个不进入的切点方法,希望大神帮忙看下问题出在哪!/*测试切面start*/@Pointcut...
  • java切面编程:概念部分(一)

    千次阅读 2019-09-30 17:25:09
    目前java切面编程在java开发及其他软件开发领域的应用十分广泛,在java1.5加入注解功能后更是如虎添翼,目前认知值停留在模糊的概念阶段:java切面编程通过jdk和cglib两种动态代理模式,可以在类和方法还有注解上...
  • 面向切面所需jar包

    2018-07-30 14:12:28
    面向切面所需jar包、、、、、、、、、、、、、、、、、、、、、、、、、
  • 定义切面注解 @Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited public @interface KpiAspectAnnotation { String desc() default ""; } 定义切面抽象类 public ...
  • 前言 分布式锁,其实原理是就是多台机器,去争抢一个资源,谁争抢成功,那么谁就持有了这把锁,然后去执行后续的业务逻辑,执行完毕后,把锁释放... 用到StringRedisTemplate类,通过AOP和切面注解的方式开启分布式...
  • Java-Spring 自定义注解切面的使用

    千次阅读 2018-08-27 21:27:52
    java注解是附加在代码中的一些元信息,用于一些工具在编译、运行时进行解析和使用,起到说明、配置的功能。 注解不会也不能影响代码的实际逻辑,仅仅起到辅助性的作用。包含在 java.lang.annotation 包中。 1:写元...
  • Java AOP切面日志处理

    2021-12-06 15:03:58
    1,引入依赖 <dependency> <groupId>org.springframework.boot</groupId> ...spring-boot-starter-aop<...2,配置日志切面 @Aspect @Component @Slf4j @Order(1) public class LogOperatio
  • 1、相关依赖包org.springframework.bootspring-boot-starter-aoporg.aspectjaspectjrt1.8.62、定义切面类package com.bz.aspect;import com.bz.service.SysLogOperationService;import org.aspectj.lang....
  • Spring中的AOP代理还是离不开Spring的IOC容器,代理的生成,管理及其依赖关系都是由IOC容器负责,Spring默认使用JDK动态代理,在需要代理类而不是代理接口的时候,Spring会自动切换为使用CGLIB代理,不过现在的项目...
  • Spring中,使用切面全局捕获异常的同时,进行自定义异常抛出捕获,方便代码书写。
  • 2.2 切面业务日志的核心实现流程 建立日志拦截器,自定义模板 创建日志处理切面 在业务接口(controller)方法上增加日志注解。 3 切面日志的实现 3.1 创建日志拦截器 修饰符 @interface 注解名 { 属性类型 属性名() ...
  • 下面是我的应用场景springAop切面,很方便。 注解 package com . yt . anno ; import java . lang . annotation . * ; @Documented //记录javadoc @Target ( ElementType . METHOD ) //运用到的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 74,064
精华内容 29,625
关键字:

java 切面 注解

java 订阅