Why the Pointcut expression is not working - java

If i keep #Pointcut("within(org.example.ShoppingCart.*)") in AuthenticationAspect.java then the authenticate method is NOT getting invoked BUT when i change to #Pointcut("within(org.example..*)") then it does get invoked.
Doesn't the 2nd PointCut below automatically include the first one?
#Pointcut("within(org.example.ShoppingCart.*)")
#Pointcut("within(org.example..*)")
i believe both of these should work.
Following is the code :
ShoppingCart.java
package org.example;
import org.springframework.stereotype.Component;
#Component
public class ShoppingCart {
public void checkout(String status)
{
System.out.println("Checkout method called");
}
}
AuthenticationAspect.java
package org.example;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
#Aspect
#Component
public class AuthenticationAspect {
#Pointcut("within(org.example.ShoppingCart.*)")
public void authenticationPointCut()
{
}
#Before("authenticationPointCut()")
public void authenticate()
{
System.out.println("Authentication is being performed");
}
}
Main.java
package org.example;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Main {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(BeanConfig.class);
ShoppingCart cart = context.getBean(ShoppingCart.class);
cart.checkout("CANCELLED");
}
}
BeanConfig.java
package org.example;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
#Configuration // Indicates this is a configuration class
#ComponentScan(basePackages = "org.example") // Indicates where to find the components/beans
#EnableAspectJAutoProxy // Enables the AspectJ features in project
public class BeanConfig {
}
i am learning spring aspect and unsure why the pointcut expression is not working .

Since the within pointcut designator limits matching to join points of certain types, the problem is your pointcut expression is matching types within ShoppingCart because of .* in the end. If you remove those characters it should work.
#Pointcut("within(org.example.ShoppingCart)")
public void authenticationPointCut(){}

Related

NoSuchBeanDefinitionException: No bean named 'authService' available

When trying to use the api, I get this error:
"org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'authService' available".
How do I make the authservice be found by the app? I've gotten a similar error before, which I tried to fix by adding all the packages you see below in the Main class.
The Main class:
package com.lvwangbeta.poplar.api;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import com.lvwangbeta.poplar.action.PoplarActionServiceApplication;
import com.lvwangbeta.poplar.feed.PoplarFeedServiceApplication;
import com.lvwangbeta.poplar.tag.PoplarTagServiceApplication;
import com.lvwangbeta.poplar.user.PoplarUserServiceApplication;
import java.util.List;
#SpringBootApplication(scanBasePackages= {"com.lvwangbeta.poplar.common","com.lvwangbeta.poplar.common.intr","com.lvwangbeta.poplar.action",
"com.lvwangbeta.poplar.api.service",
"com.lvwangbeta.poplar.feed","com.lvwangbeta.poplar.tag",
"com.lvwangbeta.poplar.user", "com.lvwangbeta.poplar.api"})
//#ComponentScan({"com.lvwangbeta.poplar.common","com.lvwangbeta.poplar.user","com.lvwangbeta.poplar.feed.dao", "com.lvwangbeta.poplar.api"})
#ComponentScan({"com.lvwangbeta.poplar.action.dao.impl","com.lvwangbeta.poplar.feed.dao.impl"})
#MapperScan({"com.lvwangbeta.poplar.action.dao","com.lvwangbeta.poplar.feed.dao","com.lvwangbeta.poplar.tag.dao"})
public class PoplarApiApplication extends WebMvcConfigurerAdapter {
public static void main(String[] args) {
//Object[] sources = {PoplarApiApplication.class,PoplarTagServiceApplication.class};
//SpringApplication.run(sources, args);
System.out.println("Started");
SpringApplication.run(PoplarApiApplication.class, args);
//SpringApplication.run(PoplarTagServiceApplication.class, args);//I hope this works
//SpringApplication.run(PoplarActionServiceApplication.class, args);
//SpringApplication.run(PoplarFeedServiceApplication.class, args);
//SpringApplication.run(PoplarUserServiceApplication.class, args);
}
#Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
super.addArgumentResolvers(argumentResolvers);
argumentResolvers.add(new RequestAttributeArgumentResolver());
}
#Override
public void addInterceptors(InterceptorRegistry registry) {
super.addInterceptors(registry);
registry.addInterceptor(new APIAccessAuthRequiredInterceptor())
.addPathPatterns("/api/v1/**")
.excludePathPatterns("/api/v1/user/login/**")
.excludePathPatterns("/api/v1/user/check/email/*")
.excludePathPatterns("/api/v1/user/register/**")
.excludePathPatterns("/api/v1/feed/of/user/**");
}
}
The AuthService class:
package com.lvwangbeta.poplar.api.service;
import com.lvwangbeta.poplar.common.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
#Service("authService")
public class AuthService {
#Autowired
private RedisTemplate<String, String> redisTemplate;
#Resource(name="redisTemplate")
private HashOperations<String, String, Object> mapOps;
public User getUserByToken(String token) {
return (User) mapOps.get("tokens:", token);
}
}
What am I missing? It's not registering even though the api link is there. I'm trying to combine many microservices to one, and so there's alot of packages.
include com.lvwangbeta.poplar.api.service in #ComponentScan
Like this :
#ComponentScan({"com.lvwangbeta.poplar.action.dao.impl","com.lvwangbeta.poplar.feed.dao.impl", "com.lvwangbeta.poplar.api.service"})
Suggestion :For simple applications avoid configuring the way above.
Keep your project structure as explained in this reference and #SpringBootApplication is enough.
https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#using-boot-locating-the-main-class

No bean named xxx available

It is a very simple program that has a main class as JavaLoader, one interface Student. Student is implemented by two classes.
I have also made a configuration class. When I instantiate the bean from the main class and call a method on Samir. A NoSuchBeanDefinitionException is thrown.
Main class (JavaLoader):
package spring;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class JavaLoader {
public static void main(String[] args) {
AnnotationConfigApplicationContext appContext = new
AnnotationConfigApplicationContext("StudentConfig.class");
Student samir = (Student) appContext.getBean("samir", Student.class);
System.out.println(samir.readsBook());
}
}
StudentConfig class:
package spring;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
#Configuration
#ComponentScan("spring")
public class StudentConfig {
}
Samir class:
package spring;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;
#Component("samir")
public class Samir implements Student{
#Autowired
#Qualifier("history")
Book book;
public Samir(Book book){
this.book = book;
}
public String readsBook(){
return book.readBook();
}
}
The expected output is that the method samir.readsBook() on JavaLoader should be executed
You need to provide a Class instance to the AnnotationConfigApplicationContext constructor:
new AnnotationConfigApplicationContext(StudentConfig.class);
note that StudentConfig.class is not the same as the string "StudentConfig.class".
Note that AnnotationConfigApplicationContext has a string-constructor as well (that's why your code still compiles), but that string is interpreted as a base package for auto-scanning rather than the configuration class name.

Primitive type dependency injection in spring boot

Can you please provide me with an example of primitive type dependency injection in spring boot. I have tried once but TestConfiguration which is my custom bean definition class does not detect or does not recognize by spring boot application.
here is my code,
//Engine class
package com.test2.projectTest;
import org.springframework.stereotype.Component;
#Component
public class Engine {
private String msg;
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
//Test Configuration
package com.test2.projectTest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
#Configuration
public class TestConfiguration {
#Bean("engine")
public Engine engine(){
Engine engine = new Engine();
engine.setMsg("Message is injected");
return engine;
}
}
//spring main application
package com.test2.projectTest;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
#SpringBootApplication
public class ProjectTestApplication {
public static void main(String[] args) {
SpringApplication.run(ProjectTestApplication.class, args);
}
}
//JUnit Test
package com.test2.projectTest;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.ApplicationContext;
import
org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.test.context.junit4.SpringRunner;
#RunWith(SpringRunner.class)
#SpringBootTest
public class ProjectTestApplicationTests {
#Test
public void contextLoads() {
ApplicationContext apc = new
AnnotationConfigApplicationContext(TestConfiguration.class);
Engine e = (Engine) apc.getBean("engine");
e.getMsg();
}
}
// Output - org.springframework.beans.factory.NoSuchBeanDefinitionException:
No bean named 'engine' available
Please suggest any solution to above issue
Add #componentscan annotation in main class and provide engine class package and it should work

AspectJ not executing the advice

I am trying to understand how AspectJ works so I built this very simple example. I can execute x() from a web browser but applaud() never gets executed. Why? How can I get it executed (apart from calling it inside x())? I am trying to do all this without creating an xml.
My environment is Java, Spring, AspectJ, IntelliJ and Windows 10.
package hello;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
#RestController
#Aspect
#Configuration
#EnableAspectJAutoProxy
public class SomeClass {
#RequestMapping("/x")
#Pointcut("execution(* hello.SomeClass.x())")
public String x() {
System.out.println("in x");
return "<div><h1>Some content</h1></div>";
}
#After("hello.SomeClass.x()")
public void applaud() {
System.out.println("CLAPCLAPCLAPCLAPCLAP");
}
}

Capturing advice execution (advising advice) in AspectJ

I'm trying to capture the execution of an advice using annotation in Maven, but it says that advice has not been applied. Here is the code:
package testMaven8;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
#Aspect
public class aspecter {
public static int a;
public void setA(int a) {
this.a = a;
}
public int getA() {
return a;
}
#Before("execution(* testMaven8.das.qwe(..))")
public void testBefore2(){
System.out.println("yoo2");
setA(102);
System.out.println(a);
}
#Before("execution (* testMaven8.aspecter.testBefore2(..))")
public void advice1(){
System.out.println("advicing advice testBefore2");
}
}
Is there something wrong with the code? I'm trying to avoid the usage of Aspect class if it's possible. Any help is appreciated.
Thanks
Advice execution is something special in AspectJ, not a normal method execution. Thus, if you want to capture advice execution you also need a special pointcut with the surprising name - adviceexecution() ;-)
Here is some sample code:
Driver application:
package de.scrum_master.app;
public class Application {
public static void main(String[] args) {
new Application().doSomething();
}
public void doSomething() {
System.out.println("Doing something");
}
}
Aspect capturing method executions:
package de.scrum_master.aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
#Aspect
public class MethodInterceptor {
#Before("execution(!static * *(..))")
public void interceptMethod(JoinPoint thisJoinPoint) {
System.out.println(thisJoinPoint);
}
}
Aspect capturing advice executions:
package de.scrum_master.aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
#Aspect
public class AdviceInterceptor {
#Before("!within(AdviceInterceptor) && adviceexecution()")
public void interceptAdvice(JoinPoint thisJoinPoint) {
System.out.println(thisJoinPoint);
}
}
Please do not try to pack the advice execution interceptor into the same aspect as another advice because you can easily end up in an endless recursion if you cannot exclude the adviceexecution() pointcut from capturing itself via !within(AdviceInterceptor).
Console log:
adviceexecution(void de.scrum_master.aspect.MethodInterceptor.interceptMethod(JoinPoint))
execution(void de.scrum_master.app.Application.doSomething())
Doing something

Categories