Spring AOP No visible constructors in class

2019-07-22 20:45发布

问题:

Error: java.lang.IllegalArgumentException: No visible constructors in class org.springframework.hateoas.config.HypermediaSupportBeanDefinitionRegistrar$DefaultObjectMapperCustomizer

Mostly, I used example given in link, and the following code can be found at github repository

Annotation:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface NeedTestClass {
}

Aspect:

@After("@args(NeedTestClass)")
public void afterReturningAtArgs() {
    log.info("aspect: after @args {}");
}

Service:

@Slf4j
@Component
public class BusinessService {

    public void logicWithAnnotatedArgs1(Child c) {
        log.info("service");
    }
}

Pojo (top class, not sub class):

@NoArgsConstructor // tried with or without
@NeedTestClass
public class Child {}

Test:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
@WebAppConfiguration
@SpringBootTest
public class AopTest {
    @Autowired
    private BusinessService myBusinessService;
    @Test
    public void testAtArgsPCD() {
        myBusinessService.logicWithAnnotatedArgs1(new Child());
    }

I attempted to examine aop and annotated class inheritance, but it seems the first step could not be ok. I have tried @annotation() and this() PCD both ok.

EDIT: So far I am wondering maybe the error is related with the bean loading sequence.

回答1:

Your GitHub project does not even compile. Have you even tested it? First by trial and error I had to add all of these dependencies:

<dependency>
  <groupId>org.springframework.data</groupId>
  <artifactId>spring-data-jpa</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
  <groupId>org.hibernate.javax.persistence</groupId>
  <artifactId>hibernate-jpa-2.0-api</artifactId>
  <version>1.0.1.Final</version>
</dependency>
<dependency>
  <groupId>com.alibaba.druid</groupId>
  <artifactId>druid-wrapper</artifactId>
  <version>0.2.9</version>
</dependency>
<dependency>
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
  <version>6.0.6</version>
</dependency>

Next, I noticed that the Maven build does not seem to start the local (127.0.0.1) database because Spring Boot says this at start-up:

(...)
2018-01-02 17:57:18.882  INFO 14480 --- [           main] com.alibaba.druid.pool.DruidDataSource   : {dataSource-1} inited
2018-01-02 17:57:20.007 ERROR 14480 --- [tionPool-Create] com.alibaba.druid.pool.DruidDataSource   : create connection error

com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure

The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
    at com.mysql.cj.jdbc.exceptions.SQLError.createCommunicationsException(SQLError.java:590) ~[mysql-connector-java-6.0.6.jar:6.0.6]
    at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:57) ~[mysql-connector-java-6.0.6.jar:6.0.6]
(...)

Would you mind refactoring your GitHub project into an MCVE first before I can check on your actual problem? This way the error is not reproduceable.

But having said this, I did notice something in your POM and Java files: Maybe the problem is not where you think it is. I can see that you want to use Lombok in combination with Spring AOP. According to my answer here, there are compatibility problems between AspectJ and Lombok. Maybe they also affect Spring AOP. So can you temporarily test without @Slf4j and other Lombok stuff? As soon as you will have fixed your project I can also test by myself.


Update after GitHub repo project has been repaired:

Now I can build and run your program, thanks. It seems that the parameter is somehow passed through to internal Spring classes you do not wish to target. So just modify your pointcut like this:

@After("@args(com.example.demosm.my.aop.NeedTestClass) && within(com.example.demosm..*)")


标签: spring-aop