I try to use aspectj for checking whether the layers of the architecture are broken, e.g. the access from controller to repository without using a service between
Now this is marking every method call to a autowired annotated within de.fhb.controller.
but how can i then limit that to Repositories for example?
The package structure looks like this:
my aspect looks like this
@Aspect
public class Layer {
@DeclareError("within(de.fhb.controller..*) && @annotation(org.springframework.beans.factory.annotation.Autowired) " )
private static final String typeWarning = "You try to access through many layers";
}
the repository:
@Repository
public interface BoxRepository extends JpaRepository<Box, Long>{
public List findByPrio(long prio);
}
and the controller that should be checked by aspects:
@RequestMapping("/box")
@Controller
public class BoxController {
@Autowired
private BoxRepository boxRepository; // negative example
@Autowired
private BoxService boxService;
@RequestMapping(value = "/")
public String list(Model model) {
List boxes = boxRepository.findAll(); // negativ example
model.addAttribute("boxes", boxes);
return "box/list";
}
for further look: repository at github
Your pointcut
within(de.fhb.controller..*) &&
execution(de.fhb.repository.BoxRepository *(..))
means in prose: Intercept any method in package de.fhb.controller
or its sub-packages which has a return type of de.fhb.repository.BoxRepository
, but in your code is no such method. So you will never see a compiler error.
;-)
Updated answer after question update:
You need to intercept calls to methods of types with a @Repository
annotation:
within(de.fhb.controller..*) &&
call(* (@org.springframework.stereotype.Repository *).*(..))
But in order to do that you need to switch from Spring AOP to full-blown AspectJ with compile-time weaving, i.e. you need to use the AspectJ compiler Ajc to compile and weave your aspect. The reason is that Spring AOP does not support the call()
pointcut, but this is what you need. An execution()
pointcut will not help you here, but that is the only one supported by a proxy-based "AOP lite" framework like Spring AOP. You just need to weave this one aspect with AspectJ, the other aspects can still use Spring AOP. But then need to take care about AspectJ not picking up your other aspects.