Spring Boot - Autowired MongoClient - spring

I got pretty confused now, I would like to use #Autowired MongoClient attribute in one of my Controller classes, but without success. The tricky part of it is that #Autowired is working from my #RestController.
#RestController
public final class WebController {
/** mongoClient */
#Autowired
private MongoClient mongoClient; <- here it's working ...
...
}
but:
#Controller
public final class MongoUsersDAO {
/** mongoClient */
#Autowired
private MongoClient mongoClient; <- not working ...
...
}
here I get null.
I do not think that the problem would be the component scan while my #SpringBootApplication is located at x.y.z, my #RestController at x.y.z.t and my #Controller at x.y.z.k packages, hence booth of them should be scanned by Spring.
(The Eclipse also marks my #Controller as a Spring class)
What else could be the problem then ?
Note:
If I add this to my #Controller it's working fine but the #Autowired still wount work:
#PostConstruct
public void init() {
System.out.println("INIT");
}
Note: In the mentioned MongoUsersDAO the autowired thing is not working at all, I've tried to get a simple property as well from the application.properties, without success.

Your problem occured because you have called new MongoUserDAO() inside your WebController class as you mentioned in the comment below your question. If you instantiate an object by hand and you have field annotated with #Autowired then this field won't be instantiated with expected instance.
Inject MongoUsersDAO directly to your WebController class as shown below, Spring will handle injecting MongoClient to MongoUserDAO class for you.
WebController :
#RestController
public final class WebController {
/** Service/Repository class*/
#Autowired
private MongoUsersDAO dao;
#GetMapping("/all")
public String getAll(){
dao.callSomeMethod();
}
}
MongoUsersDAO:
#Repository
public final class MongoUsersDAO {
/** mongoClient */
#Autowired
private MongoClient mongoClient;
...
}

Related

#ConfigurationProperties, #Value not Working YET Passing the Tests

I have a strange problem reading configuration, none of solutions I've seen seem to work. Here is my code:
#SpringBootApplication
#EnableConfigurationProperties
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Here is my properties class
#Component
#ConfigurationProperties(prefix = "my")
#Data
#ToString
#NoArgsConstructor
#AllArgsConstructor
public class MyProperties {
private String host;
private int port;
}
I then use MyProperties class in my class using #Autowired:
#Autowired
private MyProperties props;
However, I'm getting null for my props object.
Strangely, this is passing the tests just perfectly:
#SpringBootTest
class ApplicationTests {
#Autowired
private MyProperties props;
#Test
void test_configuration() {
Assertions.assertEquals(props.getHost(), "xx.xx.xx.xx");//pass!
Assertions.assertEquals(props.getPort(), xxxxxx);//pass!
}
}
It has totally refused to work, and so has #Value injection. What could I be missing?
EDIT
Here's complete code of how I'm using #Autowired on MyProperties (I've included #Value which is also not working)
#Slf4j
#Component //also tried #Configurable, #Service
public class MyService {
#Autowired
private MyProperties props;
#Value("localhost")
public String host;
public void post() {
log.info(host + props);// =null and null
}
}
EDIT2
However, I've noticed that on the controller, it works perfectly okay:
#Slf4j
#RestController
#Service
public class Main {
#Autowired
private MyProperties props;
#Value("localhost")
private String host;
#GetMapping("/post")
public void post() {
log.info(host + props);//=it's perfect!
new MyService().post();// calling MyService - where #Autowired or #Value is failing
}
}
The reason this isn't working is because the MyService you're using isn't a Spring bean, but an instance you created by yourself (using new MyService()).
To make this work, you should autowire MyService, in stead of creating your own instance:
#Slf4j
#RestController
public class Main {
#Autowired // Autowire MyService
private MyService myService;
#GetMapping("/post")
public void post() {
myService.post(); // Use the myService field
}
}
For more information, look at this Q&A: Why is my Spring #Autowired field null.
UPDATE:
new MyService() is not a "spring bean", thus can't be auto-wired with anything!;)
1. Lombok
Some people use Project Lombok to add getters and setters automatically. Make sure that Lombok does not generate any particular constructor for such a type, as it is used automatically by the container to instantiate the object.
With "such a type" ConfigurationProperties is referred in Externalized Configuration (one of my favorite chapters;) More Exact: 2.8.1. JavaBean properties binding, at the bottom of second "Note!" ;)
So this could be a reason (for strange behavior).

What will happen if i remove #Autowired from field/constructor injection but injecting that bean in another class

Suppose i have a class as,
#Repository
public class StudentServiceDao{
private final StudentClient client;
private final StudentValidator validator;
#Autowired <----
public StudentServiceDao(StudentClient studentClient){
client = studentClient;
validator = new StudentValidator(studentClient.getIdentifier());
}
public List<Student> getStudent(Request request){
StudentRS studentRS= client.getStudentList(request);
validator.validate(studentRS);
return StudentMapper.map(studentRS);
}
}
Now i have another class as,
#Component
public class StudentServiceDaoImpl{
#Autowired
private StudentServiceDao studentServiceDao;
public list<Student> retrieveStudent (Request request){
return studentServiceDao.getStudent(request);
}
}
Now if i remove #Autowired from StudentServiceDao what will happen and why ?
Autowiring can happen multiple ways.
For a few years now (currently 2020) all of these are valid ways to autowire dependencies:
Explicit constructor autowire annotation:
#Repository
public class StudentServiceDao {
private final StudentClient client;
private final StudentValidator validator;
#Autowired
public StudentServiceDao(StudentClient studentClient){
client = studentClient;
validator = new StudentValidator(studentClient.getIdentifier());
}
}
Implicit constructor autowire:
#Repository
public class StudentServiceDao {
private final StudentClient client;
private final StudentValidator validator;
public StudentServiceDao(StudentClient studentClient){
client = studentClient;
validator = new StudentValidator(studentClient.getIdentifier());
}
}
Explicit field autowire:
#Repository
public class StudentServiceDao {
#Autowired
private final StudentClient client;
#Autowired
private final StudentValidator validator;
}
Pick which ever one makes the most sense for you. I personally like implicit constructor. I think it makes instantiating the bean for testing easier with mocks. All types are valid.
5 or 6 years ago, before java config took over, there were other requirements like getters/setters needing to be present, xml files needing to specify all the beans, etc. But those are mostly gone and if you are working on a modern spring app you won't encounter them.
As to why, I have no idea, this is just how it is.

#Autowired not working in spring boot

I am working on spring-boot application. In that application #Autowired is not working for some classes.
I have below classes in spring boot application:
#Component
public class SessionUser {
private static final String SESSION_PRINCIPAL = "session.principal";
#Autowired
private HttpSession httpSession;
//more code
}
#RestController
public class RefreshUserPermissionsRequestHandler {
#Autowired
TaskTrigger taskTrigger;
#Autowired
private SessionUser sessionUser;
}
public class LocalFileUserProviderImpl {
#Autowired
private SessionUser sessionUser;
//more code
}
In RefreshUserPermissionsRequestHandler, the SessionUser bean is injecting properly, but in LocalFileUserProviderImpl it's not working. Even I tried to annotate LocalFileUserProviderImpl with #RestController and #Controller but both are not working.
Can anyone help me what is going wrong here? Please let me know if any further info is required.

Unit Test with Spring JPA - #Autowired is not working

I have a unit test and a helper class.
Unfortunely the Helper class' autowire does not work.
It works fine in MyTest class.
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations={"classpath*:context.xml"})
#Component
public class MyTest {
#Autowired
private Something something1;
#Autowired
private Something something2;
..
#Test
public void test1()
{
// something1 and something2 are fine
new Helper().initDB();
..
}
}
// Same package
public class Helper {
#Autowired
private Something something1;
#Autowired
private Something something2;
..
public void initDB()
{
// something1 and something2 are null. I have tried various annotations.
}
}
I'd like to avoid using setters because I have like 10 of those objects and different tests have different ones.
So what is required to get #Autowired working in Helper class? Thx!
You must not create the Helper class by a new statement, but you have to let spring create it to become a spring been and therefore its #Autowired fields get injected.
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations={"classpath*:context.xml"})
#Component
public class MyTest {
#Autowired
private Something something1;
#Autowired
private Something something2;
..
#Autowired
private Helper helper
#Test
public void test1() {
helper.initDB();
}
}
//this class must been found by springs component scann
#Service
public class Helper {
#Autowired
private Something something1;
#Autowired
private Something something2;
public void initDB(){...}
}
Your Helper class is not instanciated by spring ... You have to add an annotation like #component (if you are using package scan), or you can define the class as Bean in your springconfiguration class. But if you create the instance by yourself, it doesn't work

org.springframework.data.repository always null into custom UserDetailManager

In my project I've a DAO defined as a org.springframework.data.repository
#RepositoryRestResource(path = "/user")
public interface SymtUserDAO extends CrudRepository<User, Long>{
...
It works fine in controllers by #Autowired (Dependency Injection):
#Controller
public class ProveController {
#Autowired
private SymtUserDAO dao;
...
I need to use it in my custom UserDetailsManager but in here the dao is always null
public class SymtUserManager implements UserDetailsManager {
#Autowired
private SymtUserDAO dao;
I don't know if it matters but I instantiate my custom UserDetailManager in the AuthorizationServerConfigurerAdapter's constructor
/**
* This class is used to configure how our authorization server (the "/oauth/token" endpoint)
* validates client credentials.
*/
#Configuration
#EnableAuthorizationServer
#Order(Ordered.LOWEST_PRECEDENCE - 100)
protected static class OAuth2Config extends
AuthorizationServerConfigurerAdapter
{
....
public OAuth2Config() throws Exception {
UserDetailsService svc = new SymtUserManager(...
Why my working DAO (test passed in the controller) doesn't work ( it is always null) in the UserDetailsManager? what I have to do to use the DAO ( repository ) also into the UserDetailsManager?
EDIT: zeroflagL is right. I updated answer according to comments.
Your SymtUserManager is not s spring bean. Therefore it's not created and handeled by Spring bean container. Therefore spring can't inject dependency there.
You can autowire it into OAuth2Config constructor and pass it as constructor parameter to SymtUserManager:
#Configuration
#EnableAuthorizationServer
#Order(Ordered.LOWEST_PRECEDENCE - 100)
protected static class OAuth2Config extends
AuthorizationServerConfigurerAdapter
{
private SymtUserDAO dao;
#Autowire
public OAuth2Config(SymtUserDAO dao) throws Exception {
UserDetailsService svc = new SymtUserManager(dao, ...

Resources