I have a spring boot app that I am using with the Web Plugin.
In one class I have:
package com.test.company
#Component
#RestController
public class CompanyService {
#Autowired
private MongoTemplate mongoTemplate;
#Autowired
private Environment env;
And in another class I have:
package com.test.company
#Component
#RestController
public class CustomerSignUpService {
private static MongoTemplate mongoTemplate;
#Autowired
private Environment env;
#Autowired
public void setMongoTemplate(MongoTemplate mongoTemplate) {
this.mongoTemplate = mongoTemplate;
}
Both classes work but if I try to inject mongo into the CusomterSignUpService class like I did in the CompanyService class, the env is injected fine, but mongo doesn't inject and I get a null pointer exception if I try to use it.
Any thoughts? Main package is com.test.
I believe your Controller might need to look like (removed static from property):
package com.test.company
#Component
#RestController
public class CustomerSignUpService {
#Autowired
private MongoTemplate mongoTemplate;
#Autowired
private Environment env;
...
...
}
You can use #Autowired both in the attribute and in the setter, but your attribute must be an instance variable, not a static one.
So do this and your code should run fine:
package com.test.company
#Component
#RestController
public class CustomerSignUpService {
private MongoTemplate mongoTemplate;
#Autowired
private Environment env;
#Autowired
public void setMongoTemplate(MongoTemplate mongoTemplate) {
this.mongoTemplate = mongoTemplate;
}
Note that the static reserved word was taken from your attribute declaration.
Remove static from the property and try it without it
package com.test.company
#Component
#RestController
public class CustomerSignUpService {
#Autowired
private MongoTemplate mongoTemplate;
#Autowired
private Environment env;
...
...
}
Related
I wonder whether it's possible to replace all the Autowired fields with final ones and #RequiredArgsConstructor below the class declaration?
For instance, replace the following code
public class Controller {
#Autowired
private Reposiroty repository;
#Autowired
private Service service;
...
}
with something like that:
#RequiredArgsConstructor
public class Controller {
private final Reposiroty repository;
private final Service service;
...
}
Thanks in advance!
Instead of using #Value doing this:
#Service
public class MyService{
#Value("${myValue}")
private String myValue;
}
I need to get ${myValue} without annotation, and without reading the file again. How to do it?
You can get it from Environment:
#Autowired
private Environment env;
// ...
env.getProperty("myValue");
One way to access Environment is through EnvironmentAware interface.
Example :
#Service
public class MyService implements EnvironmentAware{
private String myValue;
private Environment env;
#Override
public void setEnvironment(Environment environment) {
this.env = environment;
}
public String getMyValue() {
return env.getProperty("myValue");
}
}
I have a spring boot test as below
#SpringBootTest(class=AppConfig.class)
Public class AppTest{
#Autowired
private Product product
#Test
Public void test(){
.....
.....
}
}
My AppConfig.class is as below
Public clas AppConfig{
#Mock
EMailService emailService;
public AppConfig(){
MockitoAnnotations.initMocks(this)
}
#Bean
Public Product getProduct(){
return new Product();
}
}
Class Product{
#Autowired
private EMailService emailService
.....
......
}
Even after i defined #Mock EMailService emailService, whem i run the test, I get error EMailService bean not defined.
In your AppTest class
#SpringBootTest(class=AppConfig.class)
public class AppTest{
#Mock
private EMailService emailService;
#InjectMocks
private Product product;
#Test
public void test(){
.....
.....
}
}
Also, I think you do not need the definitions in the AppConfig class anymore
I have two datasources that are equal in their structure but not in their Data.
My application has to deal with both of them at the same time.
I have controller, servie, dao structure that looks like this.
Controller Modell:
#Controller
public abstract class MyFancyControllerModell{
private MyService service;
public MyFancyControllerModell (MyService service){
this.service = service;
}
#RequestMapping(....)
public void editSomeData(String data){....}
}
Controller implementation:
#Controller
#RequestMapping(...)
public class MyControllerImpl1 extends MyFancyControllerModell{
#Autowired
public MyControllerImpl1(#Qualifier("myServiceInstance1") MyService service){
super(service);
}
}
#Controller
#RequestMapping(...)
public class MyControllerImpl2 extends MyFancyControllerModell{
#Autowired
public MyControllerImpl2(#Qualifier("myServiceInstance2") MyService service){
super(service);
}
}
And the Service:
public class MyService{
private MyDao myDao;
public MyService(MyDao myDao){
this.myDao = myDao;
}
#Transactional
public void editSomeData(String data){...}
}
I create the Beans in my configuration class like this:
private DataSource lookupDataSource(final String jndiName) {
final JndiDataSourceLookup dsLookup = new JndiDataSourceLookup();
dsLookup.setResourceRef(true);
return dsLookup.getDataSource(jndiName);
}
#Bean
public DataSource dataSource1(){
return lookUpDataSource("dataSource1");
}
#Bean
public DataSource dataSource2(){
return lookUpDataSource("dataSource2");
}
#Bean
public MyService myServiceInstance1(#Qualifier("dataSource1") DataSource dataSource){
return new(MyService(new MyDao(dataSource))));
}
#Bean
public MyService myServiceInstance1(#Qualifier("dataSource1") DataSource dataSource){
return new(MyService(new MyDao(dataSource)));
}
My question is, is it possible to create transactionmanagers for both datasources without the need to declare in the service layer which transactionmanager is used?
I tried creating them as bean just like the services but that did not work.
Check out here the answers for previous quesion related to transaction manager...
https://stackoverflow.com/a/1961853/7504001
Is there any way to inject non-mocked objects with #InjectMocks?
My Setup has a UserSignupService with dependencies to a MailService and a UserRepository (a Spring Data Repository). I've a unit test creating a spy of the MailService and I annotated the UserSignupService with #InjectMocks. Sadly this won't inject the UserRepository (non-mocked) into the service class.
Combining #InjectMocks with #Autowired won't inject the mocked MailService, but the bean from the application context.
MockitoAnnotations.initMocks() is run in AbstractServiceTest.setUp(). This class also holds the configuration of the the unit test (SpringJunit4TestRunner, etc.)
public class UserSignupServiceTest extends AbstractServiceTest {
#Autowired #Spy
private MailService<UserActivationMail> mailService;
#InjectMocks
private UserSignupServiceImpl service;
#Before
public void setUp() throws Exception {
super.setUp();
}
}
#Service
public class UserSignupServiceImpl implements UserSignupService {
private final UserRepository repository;
private final MailService<UserActivationMail> mailService;
#Autowired
public UserSignupServiceImpl(UserRepository repository,
MailService<UserActivationMail> mailService) {
this.repository = repository;
this.mailService = mailService;
}
//methods...
}
You need to initialize your Mockito MockitoAnnotations.initMocks(this);
Here is sample Spring JUnit test class I have
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = { "classpath:config/spring-context.xml" })
public class SpringKPTest {
#Autowired
SomeClassA SomeClassA;
#Mock
SomeClassB SomeClassB;
#Before
public void init(){
MockitoAnnotations.initMocks(this);
}
}