Sumanth Jois
Sumanth Jois

Reputation: 3234

Spring aop after method not being called

Hello I am trying to update the database using Spring aop's @After annotation but the method annotated with @After is not being called.

This my SignupController:

package com.jpizza.web;

import com.jpizza.model.Customer;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import static org.springframework.web.bind.annotation.RequestMethod.GET;
import static org.springframework.web.bind.annotation.RequestMethod.POST;


@Controller
@RequestMapping("/signup")
public class SignupController {

    @RequestMapping(method=GET)
    public String signup(){
        return "signup";
    }

    @RequestMapping(method=POST)
    public String formHandler(Customer customer){
        return "home";
    }
}

This is my Aspect class:

    package com.jpizza.db;

import com.jpizza.model.Customer;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;

/**
 * Creed is a worker at jois pizza who registers users
 */
@Aspect
public class Creed implements CustomerDao{

    @Autowired
    private JdbcTemplate template;

    //This method is not being executed
    @After("execution(* com.jpizza.SignupController.formHandler(..)) && args(customer)")
    @Override
    public void saveCustomer(Customer customer) {
        System.out.println("About to update data");
        String sql = "INSERT INTO customer (username, email, password) VALUES (?,?,?)";
        template.update(sql, customer.getUsername(), customer.getEmail(),customer.getPassword());
    }

}

This is my WebConfig.class:

    @Configuration
@EnableWebMvc
@ComponentScan("com.jpizza.web")
@PropertySource("classpath:database.properties")
@EnableAspectJAutoProxy
public class WebConfig extends WebMvcConfigurerAdapter{

    @Autowired
    private Environment env;

    @Bean
    public ViewResolver viewResolver(){
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("/WEB-INF/views/");
        resolver.setSuffix(".jsp");
        resolver.setExposeContextBeansAsAttributes(true);

        return resolver;
    }

    @Bean
    public DataSource dataSource(){
        DriverManagerDataSource dataSource = new DriverManagerDataSource(); 
        dataSource.setDriverClassName(env.getRequiredProperty("jdbc.driverClassName"));
        dataSource.setUrl(env.getRequiredProperty("jdbc.url"));
        dataSource.setUsername(env.getRequiredProperty("jdbc.username"));
        dataSource.setPassword(env.getRequiredProperty("jdbc.password"));
        return dataSource;
    }

    @Bean
    public JdbcTemplate jdbcTemplate(DataSource source){
        JdbcTemplate jt = new JdbcTemplate(source);
        jt.setResultsMapCaseInsensitive(true);
        return jt;
    }

}

There ares no errors being logged. I am trying to execute saveCustomer(Customer) after formHandler(Customer) is executed but it's not working. The page is being redirected home.jsp can someone please tell me where I am going wrong??

Edit:

I changed my code as suggested but still the @After is not being executed

WebConfig.java:

@Configuration
@EnableWebMvc
@ComponentScan("com.jpizza.web")
@PropertySource("classpath:database.properties")
@EnableAspectJAutoProxy
public class WebConfig extends WebMvcConfigurerAdapter{

    @Autowired
    private Environment env;

    //added creed as a bean        
    @Bean
   public Creed creed(){
       return new Creed();
   }

    @Bean
    public ViewResolver viewResolver(){
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("/WEB-INF/views/");
        resolver.setSuffix(".jsp");
        resolver.setExposeContextBeansAsAttributes(true);

        return resolver;
    }

    @Bean
    public DataSource dataSource(){
        DriverManagerDataSource dataSource = new DriverManagerDataSource(); 
        dataSource.setDriverClassName(env.getRequiredProperty("jdbc.driverClassName"));
        dataSource.setUrl(env.getRequiredProperty("jdbc.url"));
        dataSource.setUsername(env.getRequiredProperty("jdbc.username"));
        dataSource.setPassword(env.getRequiredProperty("jdbc.password"));
        return dataSource;
    }

    @Bean
    public JdbcTemplate jdbcTemplate(DataSource source){
        JdbcTemplate jt = new JdbcTemplate(source);
        jt.setResultsMapCaseInsensitive(true);
        return jt;
    }

}

Creed.java:

    @Aspect
public class Creed implements CustomerDao{

    @Autowired
    private JdbcTemplate template;
    //changed the package name
    @After("execution(* com.jpizza.web.SignupController.formHandler(..)) && args(customer)")
    @Override
    public void saveCustomer(Customer customer) {
        System.out.println("About to update data");
        String sql = "INSERT INTO customer (username, email, password) VALUES (?,?,?)";
        template.update(sql, customer.getUsername(), customer.getEmail(),customer.getPassword());
    }




}

Upvotes: 1

Views: 1565

Answers (2)

Patrick
Patrick

Reputation: 935

You have two problems with your configuration:

  • Spring does not know anything about your aspect, you have to annotate it with one of Spring's stereotype annotations (e.g. @Component), or define it via @Bean annotation inside your WebConfig class
  • There is a typo in your pointcut definition, as pointed out by the first comment :)

Upvotes: 1

Hej
Hej

Reputation: 91

The class SignUpController does not implement an interface. Try enabling proxyTargetClass in the @EnableAspectJAutoProxy

@EnableAspectJAutoProxy(proxyTargetClass = true)

Upvotes: 0

Related Questions