Reputation: 23
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;
}
}
Upvotes: 0
Views: 1280
Reputation: 7131
Why the Aspect does not work
Employee
instance is not a Spring bean. Spring AOP can only advice a bean. Please read through reference documentation@Before
and @After
point cut expressions are not correct to intercept the method calls.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) {..}
Upvotes: 1