2

When I create a class annotated with @Context and run a Micronaut application, the @PostConstruct method works.

Example:

package com.example;

import io.micronaut.context.annotation.Context;

import javax.annotation.PostConstruct;

@Context
public class ClassHello1 {

    @PostConstruct
    public void sayHello() {
        System.out.println("Hello from ClassHello1");
    }

    public void doSmth() {
        System.out.println("Doing something...");
    }
}

When I remove @Context annotation from the class ClassHello1 and create a bean with a scope @Context inside @Factory class, @PostConstruct method inside ClassHello1 doesn't work.

Example:

package com.example;

import io.micronaut.context.annotation.Context;
import io.micronaut.context.annotation.Factory;

@Factory
public class FactoryClass {


    @Context
    public ClassHello1 classHello1() {
        return new ClassHello1();
    }
}
-------
package com.example;

import javax.annotation.PostConstruct;

public class ClassHello1 {

    @PostConstruct
    public void sayHello() {
        System.out.println("Hello from ClassHello1");
    }

    public void doSmth() {
        System.out.println("Doing something...");
    }
}

Even if I create another @Context bean and call a method doSmth() of ClassHello1 bean, @PostConstruct in ClassHello1 doesn't work anyway.\

package com.example;

import io.micronaut.context.annotation.Context;
import jakarta.inject.Inject;

import javax.annotation.PostConstruct;

@Context
public class ClassHello2 {

    @Inject
    private ClassHello1 classHello1;

    @PostConstruct
    public void init() {
        classHello1.doSmth();
    }
}

In this example doSmth() method of classHello1 bean is invoked, but annotated with @PostConstruct sayHello() doesn't work.

May you explain to me how can I instantiate ClassHello1 in @Factory class and make its @PostConstruct method work?

Thank you.

nikiforov.java
  • 229
  • 4
  • 12

1 Answers1

3
public ClassHello1 classHello1() {
        return new ClassHello1(); // <1>
    }
  1. Creating the bean with new will not trigger the @PostConstruct

For example:

import jakarta.annotation.PostConstruct;
import jakarta.inject.Singleton; //preferred over javax

@Singleton // only one instance of the bean will exist (lazy initialization)
// @Prototype // new instance of the bean is created each time it is injected (lazy)
// @Context // created at the same time as the ApplicationContext (eager)
public class Hello {
    @PostConstruct
    public void sayHello() {
        System.out.println("Hello World!");
    }

    public void doSmth() {
        System.out.println("Doing something...");
    }
}

@Controller("/hello")
public class HelloController {

    private final Hello hello;

    public HelloController(Hello hello) {
        this.hello = hello;
    }

    @Get("/injected")
    public String injected() {
        hello.doSmth();
        return "hello.sayHello() was called";
    }

    @Get("/instantiated")
    public String instantiated() {
        Hello h = new Hello();
        h.doSmth();
        return "hello.sayHello() was NOT called";
    }
}
ShingJo
  • 614
  • 1
  • 7
  • If it is in class annotated @Factory and a method where we write ```return new ClassHello1();``` is annotated with one of bean scope annotations, Micronaut creates a bean. The problem is that when we create a bean inside @Factory class it simply ignores @PostConstruct. As I found out it is the expected behavior of Micronaut. In this case, we need to call an init method manually. – nikiforov.java Jul 22 '22 at 18:15
  • Does Spring or some other framework call `@PostConstruct` on a bean without a scope (Singleton,Context)? – ShingJo Jul 22 '22 at 19:10
  • In the case of Spring, a method annotated with ```@PostConstruct``` is called if a bean is created by a method annotated with ```@Bean ``` – nikiforov.java Jul 22 '22 at 19:34