在@Bean被调用之前,在bean初始化后调用方法。

huangapple go评论81阅读模式
英文:

Call method after bean initialization but before @Bean called

问题

@Configuration
public class MyAppConfiguration extends MyBaseAppConfiguration {
@Bean
public MyDAOBean getMyDAOBean() {
boolean isEmpty = myString.isEmpty();
return new MyDAOBean();
}
}

@Component
@ConfigurationProperties(prefix="hey")
@Getter
@Setter
public class MyBean {
private String myString;
}

public class MyBaseAppConfiguration {
@Autowired
private MyBean myBean;

protected String myString;

//I need some annotation to call this (@PostConstruct maybe?)
public void setMyString() {
    this.myString = myBean.getMyString();
}

}

I want to set myString with something that I got from myBean. So I need some annotation to call the method that sets this field after myBean is initialized but before getMyDAOBean is called. @PostConstruct currently works for this situation, but I need to be sure if it always works. Does it do the job, or is there something I don't know, and this is risky?

Please ignore the simplicity of the example. myBean.getMyString() in getMyDAOBean would be easier, but it's more complex in reality. Just focus on the problem.

Edit: How about the setter-injection way? Does it make any difference? Is it safer or something else?

public class MyBaseAppConfiguration {
protected String myString;

@Autowired
public void setMyString(MyBean myBean) {
    this.myString = myBean.getMyString();
}

}

英文:
@Configuration
public class MyAppConfiguration extends MyBaseAppConfiguration {
	@Bean
	public MyDAOBean getMyDAOBean() {
        boolean isEmpty = myString.isEmpty();
		return new MyDAOBean();
	}
}

@Component
@ConfigurationProperties(prefix="hey")
@Getter
@Setter
public class MyBean {
    private String myString;
}


public class MyBaseAppConfiguration {
    @Autowired
    private MyBean myBean;

    protected String myString;

	//I need some annotation to call this (@PostConstruct maybe?)
	public void setMyString() {
        this.myString= myBean.getMyString();
	}
}

I want to set myString with something that I got from myBean. So I need some annotation to call method that I set this field after myBean initiliazed but before getMyDAOBean called. @PostConstruct currently working for this situation but I need to be sure if it is always working. Does it do the job or there is something I don't know and this is risky?

Please ignore simplicity of example. myBean.getMyString() in getMyDAOBean would be more easy but It's more complex in real, just focus on the problem.

Edit: How about setter-injection way? Does it make any difference? More safety or else?

public class MyBaseAppConfiguration {
    protected String myString;

	@Autowired
	public void setMyString(MyBean myBean) {
        this.myString= myBean.getMyString();
	}
}

答案1

得分: 1

你可以将MyBean添加为构造函数注入。

public class MyBaseAppConfiguration {
    protected String myString;

    @Autowired
    public MyBaseAppConfiguration(MyBean myBean){
        myString = myBean.getMyString();
    }
}
英文:

You can add MyBean as a constructor injection.

public class MyBaseAppConfiguration {
    protected String myString;

    @Autowired
    public MyBaseAppConfiguration(MyBean myBean ){
      myString = myBean.getMyString();
    }

}

答案2

得分: 1

The creation of the bean for MyDAOBean seems to have some dependency on a computed value based on the property of MyBean.

@Conditional 注解以及自定义条件可以用来执行所需的操作;在这种情况下是 myString.isEmpty()

import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;

import java.util.Objects;

public class MyStringIsEmpty implements Condition {

	@Override
	public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
		// 获取 MyBean 的 Spring Bean
		MyBean myBean = Objects.requireNonNull(context.getBeanFactory()).getBean(MyBean.class);

		// 获取 myString 属性
		String myString = myBean.getMyString();

		// 执行所需的评估
		boolean isEmpty = myString.isEmpty();

		return isEmpty; // 如果为 true,则创建该 Bean
	}
}

使用自定义条件。

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;

@Bean
@Conditional(MyStringIsEmpty.class)
public MyDAOBean getMyDAOBean() {
    return new MyDAOBean();
}
英文:

The creation of the bean for MyDAOBean seems to have some dependency on a computed value based on the property of MyBean.

The @Conditional annotation alongside a custom condition can be used to do the operations required; myString.isEmpty() is this case.

import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;

import java.util.Objects;

public class MyStringIsEmpty implements Condition {

	@Override
	public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
		// Get the spring bean for MyBean
		MyBean myBean = Objects.requireNonNull(context.getBeanFactory()).getBean(MyBean.class);
	
		// Get the property of myString
		String myString = myBean.getMyString();
	
		// perform your desired evaluation
		boolean isEmpty = myString.isEmpty();
	
		return isEmpty; // if true, the bean will be created
	}
}

Using the custom condition.

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;

@Bean
@Conditional(MyStringIsEmpty.class)
public MyDAOBean getMyDAOBean() {
    return new MyDAOBean();
}

huangapple
  • 本文由 发表于 2023年4月4日 15:46:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/75926752.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定