Custom Annotation | Not working on setters

Abhishek Bansal :

I have a requirement of making a model class field as encrypted. Approach I took is to create a custom annotation. Where-ever I will have annotation it says I will encrypt its value.

Target is to create a field/method annotation. If its a method annotation then I will annotate the Setter.

I have written code but it is not working. Kindly help.

Pojo Class where I want to encrypt salary.

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;
    }


}


Custom Annotation

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

}

Class EmployeeController

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 EmployeeService

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;
    }
}
R.G :

Why the Aspect does not work

  1. Employee instance is not a Spring bean. Spring AOP can only advice a bean. Please read through reference documentation
  2. @Before and @After point cut expressions are not correct to intercept the method calls.
  3. Encryptvalue is defined as @Target(ElementType.FIELD) and the example shows the usage as @Target(ElementType.METHOD) . The code should ideally not compile.

If the Employee class can be made a Spring managed bean ( a scoped bean in this case) , both the annotation based @Around advices will work as expected. Similarly , modifying the Pointcut expression as follows should intercept the EmployeeService.createEmployee() method call . To advice all method calls of EmployeeService , remove the and args(name,empId) part of the Pointcut Expression.

example :

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

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=361545&siteId=1