自定义注释 |不在二传手上工作

Custom Annotation | Not working on setters

我需要对模型 class 字段进行加密。我采用的方法是创建自定义注释。无论我在哪里都会有注释,它说我将加密它的值。

目标是创建一个 field/method 注释。如果它是方法注释,那么我将注释 Setter.

我已经编写了代码,但它不起作用。请帮忙。

PojoClass我要加密工资的地方

package com.example.springaop.model;

import com.example.springaop.customannotation.CustomAnnotation;
import com.example.springaop.customannotation.Encryptvalue;

public class Employee {

    private String empId;
    private String name;
    private int salary;

    public String getName() {
        return name;
    }

    @CustomAnnotation
    public void setName(String name) {
        this.name = name;
    }

    public String getEmpId() {
        return empId;
    }

    public void setEmpId(String empId) {
        this.empId = empId;
    }

    public int getSalary() {
        return salary;
    }
    @Encryptvalue
    public void setSalary(int salary) {
        this.salary = salary;
    }


}


自定义注释

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Encryptvalue {

}

Class 雇员控制器

package com.example.springaop.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.example.springaop.customannotation.LogExecutionTime;
import com.example.springaop.model.Employee;
import com.example.springaop.service.EmployeeService;


@RestController
public class EmployeeController {

    @Autowired
    private EmployeeService employeeService;

    @RequestMapping(value = "/add/employee", method = RequestMethod.GET)
    @LogExecutionTime
    public Employee addEmployee(@RequestParam("name") String name, @RequestParam("empId") String empId) throws InterruptedException {
        return employeeService.createEmployee(name, empId,1000);
    }

    @RequestMapping(value = "/remove/employee", method = RequestMethod.GET)
    public String removeEmployee( @RequestParam("empId") String empId) {

        employeeService.deleteEmployee(empId);

        return "Employee removed";
    }

}

Class 员工服务

package com.example.springaop.service;


import org.springframework.stereotype.Service;

import com.example.springaop.customannotation.CustomAnnotation;
import com.example.springaop.model.Employee;


@Service
public class EmployeeService {

    @CustomAnnotation
    public Employee createEmployee(String name, String empId, int salary) {
        Employee emp = new Employee();
        emp.setName(name);
        emp.setEmpId(empId);
        emp.setSalary(salary);
        return emp;
    }

    public void deleteEmployee(String empId) {

    }
}

Class EmployeeServiceAspect

package com.example.springaop.aspect;

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

@Aspect
@Component
public class EmployeeServiceAspect {

    @Before(value = "execution(* com.example.springaop.service.EmployeeService.*(..)) and args(name,empId)")
    public void beforeAdvice(JoinPoint joinPoint, String name, String empId) {
        System.out.println("Before method:" + joinPoint.getSignature());

        System.out.println("Creating Employee with name - " + name + " and id - " + empId);
    }

    @After(value = "execution(* com.example.springaop.service.EmployeeService.*(..)) and args(name,empId)")
    public void afterAdvice(JoinPoint joinPoint, String name, String empId) {
        System.out.println("After method:" + joinPoint.getSignature());

        System.out.println("Successfully created Employee with name - " + name + " and id - " + empId);
    }

    @Around("@annotation(com.example.springaop.customannotation.LogExecutionTime)")
    public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
        long start = System.currentTimeMillis();
        Object proceed = joinPoint.proceed();
        long executionTime = System.currentTimeMillis() - start;
        System.out.println(joinPoint.getSignature() + " executed in " + executionTime + "ms");
        return proceed;
    }


    @Around("@annotation(com.example.springaop.customannotation.CustomAnnotation)")
    public Object customAnnotation(ProceedingJoinPoint joinPoint) throws Throwable {
        Object proceed = joinPoint.proceed();
        System.out.println(joinPoint.getSignature() + "############## Executed customAnnotation #################");
        return proceed;
    }

    @Around("@annotation(com.example.springaop.customannotation.Encryptvalue)")
    public Object Encryptvalue(ProceedingJoinPoint joinPoint) throws Throwable {
        Object proceed = joinPoint.proceed();
        System.out.println(joinPoint.getSignature() + "############## Executed Encryptvalue Annotation #################");
        return proceed;
    }
}

为什么看点不起作用

  1. Employee 实例不是 Spring bean。 Spring AOP 只能建议一个bean。请仔细阅读 reference documentation
  2. @Before@After 切入点表达式不正确,无法拦截方法调用。
  3. Encryptvalue 定义为 @Target(ElementType.FIELD) 并且该示例显示用法为 @Target(ElementType.METHOD) 。理想情况下,代码不应编译。

如果 Employee class 可以成为一个 Spring 托管 bean(在这种情况下是一个作用域 bean),基于注释的 @Around 建议都将作为预期的。同样,按如下方式修改 Pointcut 表达式应该拦截 EmployeeService.createEmployee() 方法调用。要建议 EmployeeService 的所有方法调用,请删除切入点表达式的 and args(name,empId) 部分。

示例:

@After(value = "execution(* com.example.springaop.service.EmployeeService.*(..)) and args(name,empId,salary)")
public void afterAdvice(JoinPoint joinPoint, String name, String empId,int salary) {..}