I have a pojo class which i need to inject in component. how to inject pojo object in spring?
For example
RestClass is under Module(like one microservice). Pojo Value should be injected here only. service class and pojo is different module.
#Controller
public class RestClass {
#Autowired
private ServiceClass serviceClass;
// How to apply MyConfig pojo object into ServiceClass
//like MyConfig.Builder().limit(100).build();
#PostMapping("/business")
private void callDoBusiness(){
serviceClass.doBusiness();
}
}
//// ServiceClass and Pojo class is under one module. Pojo object should not construct here. should be passed from another module
#Service
public class ServiceClass {
#Autowired
private MyConfig myConfig;
public void doBusiness(){
System.out.println(myConfig.getLimit())
}
}
#Builder
#Getter
public class MyConfig {
private int limit;
.
.
}
#Bean annotation is used in your case. For example:
Create some configuration file with #Configuration annotation. It doesn't matter where you create your Config configuration class or how you name it. You can even have multiple #Configuration classes across your project.
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
#Configuration
class Config {
// configure your MyConfig class here as a bean
#Bean
public MyConfig myConfig() {
return MyConfig.Builder().limit(100).build();
}
}
Now you can autowire it wherever you use it as in you example.
You can use #Configuration and #Bean. Something like this
AppConfig.java
#Configuration
public class AppConfig {
#Bean
public PojoClass getBean(){ return new PojoClass();}
}
You can use #Bean
#Configuration
public class Config {
#Bean
public MyConfig MyConfig() {
return new MyConfig();
}
}
Related
I have 2 spring boot microservice let's say core and persistence. where persistence has a dependency on core.
I have defined an interface in core whose implementation is inside persistence as below:
core
package com.mine.service;
public interface MyDaoService {
}
Persistence
package com.mine.service.impl;
#Service
public class MyDaoServiceImpl implements MyDaoService {
}
I am trying to inject MyDaoService in another service which is in core only:
core
package com.mine.service;
#Service
public class MyService {
private final MyDaoService myDaoService;
public MyService(MyDaoService myDaoService) {
this.myDaoService = myDaoService;
}
}
while doing this i am getting this weird error:
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 0 of constructor in com.mine.service.MyService required a bean of type 'com.mine.service.MyDaoService' that could not be found.
Action:
Consider defining a bean of type 'com.mine.service.MyDaoService' in your configuration.
can anyone explain me why ?
NOTE: i have already included com.mine.service in componentscan of springbootapplication as below
package com.mine.restpi;
#SpringBootApplication
#EnableScheduling
#ComponentScan(basePackages = "com.mine")
public class MyRestApiApplication {
public static void main(String[] args) {
SpringApplication.run(MyRestApiApplication.class, args);
}
}
Try adding the #Service annotation to your impl classes and the #Autowired annotation to the constructor.
// Include the #Service annotation
#Service
public class MyServiceImpl implements MyService {
}
// Include the #Service annotation and #Autowired annotation on the constructor
#Service
public class MyDaoServiceImpl implements MyDaoService {
private final MyService myService ;
#Autowired
public MyDaoServiceImpl(MyService myService){
this.myService = myService;
}
}
As stated in the error message hint: Consider defining a bean of type 'com.mine.service.MyDaoService' in your configuration to solve this problem you can define in your package com.mine a configuration class named MyConfiguration annotated with #Configuration including a bean named myDaoService like below:
#Configuration
public class MyConfiguration {
#Bean
public MyDaoService myDaoService() {
return new MyDaoServiceImpl();
}
}
Try the following, move MyRestApiApplication class to com.mine package and remove #ComponentScan annotation.
package com.mine;
#SpringBootApplication
#EnableScheduling
public class MyRestApiApplication {
public static void main(String[] args) {
SpringApplication.run(MyRestApiApplication.class, args);
}
}
I have a Spring boot 2.3.3.RELEASE project.
Main Application class,
#SpringBootApplication()
public class TestApplication {
...
}
#ConfigurationProperties(prefix = "test")
public class TestProperties {
...
}
#Configuration
#EnableConfigurationProperties({TestProperties.class})
public class TestConfiguration {
}
#Service
public class AmazonEmailService {
private final AmazonSimpleEmailService client;
#Autowired
private TestProperties props;
public AmazonEmailService() {
props.getEmail(); // Here props is null ...
}
}
Here, TestProperties autowiring is null in AmazonEmailService. Not sure what is missing.
Other Autowiring works in other classes.
Can you use #Autowired on the constructor instead?
private TestProperies props;
#Autowired
public AmazonEmailService(TestProperties props){
this.props=props;
props.getEmail(); //Ok now.
}
This is because using #Autowired on property, Spring inject the value AFTER object create. But in your case, you try to use the props inside the contructor. At that moment, it's still null
Add #Component annotation on TestProperties class
Given a class:
class MyConfiguration {
#Bean
String bean() {
return new String();
}
}
as you may notice it does not have #Configuration annotation.
How can I make it behave like it has #Configuration annotation, but not adding it?
#Bean annotation should not work in Lite Mode, https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/context/annotation/Bean.html
Something like:
#Configuration
class MainConfiguration {
#Bean
MyConfiguration myConfiguration() {
MyConfiguration myConfiguration = do_some_spring_magic();
// myConfiguration behaving like it's having #Configuration here
return myConfiguration;
}
}
I dont understand what is the use case you are trying to achieve here.. But if you are looking for programatically registering beans into the Spring Context then you can do it as below.
#Configuration
public class MyBeanRegisterFactory implements BeanDefinitionRegistryPostProcessor, PriorityOrdered {
#Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanRegistry) throws BeansException {
//depending on some condition you can do the below line
beanRegistry.registerBeanDefinition("myBeanClass", new RootBeanDefinition("com.mybean.MyBeanClass"));
}
#Override
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE;
}
}
In Your case, the bean definitions inside the class MyConfiguration can be programatically registered as below into to the spring context.
http://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/beans/factory/support/BeanDefinitionRegistryPostProcessor.html
I have created a custom API jar library where I'd like to provide some commonly used services.
But I'd like to use and autowire some of these services optionally in my implementation projects. They should not get autowired automatically.
How could I tell Spring explicit to include the following StatsLogger?
API jar:
package my.spring.config
//#Component
public class MyStatsLogger {
#Autowired
private MyService someOtherServiceForLogging;
#Scheduled(fixedDelay = 60000)
public void log() {
//logging
}
}
IMPL project:
#Configuration
#EnableScheduling
public class AppConfig {
}
Simply add the service to your context:
#Configuration
#EnableScheduling
public class AppConfig {
#Bean
public MyStatsLogger myStatsLogger() {
return new MyStatsLogger();
}
}
Since MyStatsLogger has a default constructor, all you need to is the following:
#Configuration
#EnableScheduling
public class AppConfig {
#Bean
public MyStatsLogger myStatsLogger() {
return new MyStatsLogger();
}
}
The MyService dependency in MyStatsLogger will automatically be wired by Spring if of course there is a bean of type MyService declared.
I have the following Spring Java configuration set up:
#Configuration
public class FooConfig {
#Autowired
private IReferenceDataDAO referenceDataDAO;
#Bean
public IReferenceDataService getReferenceDataService() {
return new ReferenceDataServiceImpl(referenceDataDAO);
}
}
I am trying to reference the ReferenceDataService bean in another configuration class using the #Autowire property:
#Configuration
public class BarConfig {
#Autowired
private IRuleService ruleService;
#Autowired
private IReferenceDataService referenceDataService;
}
Here is the config that defines the IReferenceDataDAO:
#Configuration
public class FooBarConfig {
#Bean
public IReferenceDataDAO getReferenceDataDAO() {
return new ReferenceDataDAOImpl(getStaticData(), getMapper());
}
}
Here is the ReferenceDataServiceImpl:
public class ReferenceDataServiceImpl implements IReferenceDataService {
private IReferenceDataDAO dao;
public ReferenceDataServiceImpl(IReferenceDataDAO dao) {
this.dao = dao;
}
The above configs are imported in a master config class:
#Configuration
#Import({
FoosAppConfig.class,
BarAppConfig.class,
FooBarAppConfig.class,
})
I am noticing that this configuration leads to the referenceDAO in the ReferenceDataServiceImpl being set to null. What am I doing wrong? Shouldn't that #Autowire annotation ensure that my bean is fully configured before setting it?
BarConfig needs to import FooConfig
#Import({ FooConfig.class })
Try this:
#Configuration
#Import({ FooConfig.class })
public class BarConfig {
#Autowired
private IRuleService ruleService;
#Autowired
private IReferenceDataService referenceDataService;
}
This allows BarConfig to get access to the IReferenceDataService bean.