spring auto-wire failed when inject a dependent bean into a #component java class - spring

I have a Service class with #Component annotation, and this bean dependent a DAO like this:
#Component
public class CustomerService
{
#Setter
private CustomerDAO customerDAO;
}
and XML file goes like this:
<context:component-scan base-package="com.mkyong.customer" />
<bean id="customerDAO" class="com.mkyong.customer.dao.CustomerDAO" autowire="byName"></bean>
But, after the app is running, the field customerDAO can't been injected. If I replace #Setter with #Resource, that's will be fine. I deeply wonders, why the #Componet bean can't be injected with setter methods.
I'm using Spring 2.5.6;

In order to inject on setter, you will have to create a setter and annotate it with #Autowired.
#Component
public class CustomerService {
private CustomerDAO customerDAO;
#Autowired
public void setCustomerDAO(CustomerDAO customerDAO) {
this.customerDAO = customerDAO;
}
}

Related

I can't autowire Service class in Spring Boot Test

I created Dao Repository that uses jdbc for working with DB.
I autowired this repository in my Service class.
Then I try to autowire my service class in my test class.
#SpringBootTest
public class ServiceTest {
#MockBean
private Dao dao;
#Autowired
private Service service;
#Test
void whenSomething_thanSomething() {
when(Dao.getStatus(anyString())).thenReturn("green");
assertEquals(0, service.getStatus(""));
}
//other tests...
}
#Service
public class Service {
private DaoImpl daoImpl;
#Autowired
public Service(DaoImpl daoImpl) {
this.daoImpl = daoImpl;
}
//...
}
#Repository
public class DaoImpl omplements Dao {
private NamedParameterJdbcOperations jdbc;
#Autowired
public DaoImpl(NamedParametedJdbcOperations jdbc) {
this.jdbc = jdbc;
}
//...
}
When I start test I get the next error:
Parameter 0 of constructor in Service required a bean of type DaoImpl that could not be found.
How can I resolve my problem?
Since you inject DaoImpl in your service-class you were probably intending to mock DaoImpl instead of Dao:
#SpringBootTest
public class ServiceTest {
#MockBean
private DaoImpl daoImpl;
...
}

Advantages of injecting by ObjectProvider in Spring

Could you clarify what is the reason for the autowiring by ObjectProvider, if I can autowire the bean by class or interface?
public class MyBean {...}
public class MyService {
#Autowire
private ObjectProvider<MyBean> myBean;
}
vs
public class MyService {
#Autowire
private MyBean myBean;
}
Are the pros only in having the optionality check (getIfAvailable) and not-unique check (getIfUnique) methods?

#Autowired is not working for CrudRepository

I have problems injecting a repository, there is no problem injecting a Service. Im injecting the repo in a service:
#Service
public class AuthorService {
#Autowired
private AuthorRepository repository;
public String getAll(){return "XXXXX";}
}
and the repository is:
public interface AuthorRepository extends CrudRepository<Author, Integer> {
}
And my code structure is the following:
with the main class:
#SpringBootApplication
public class AuthorBookGraphqlApplication {
public static void main(String[] args) {
SpringApplication.run(AuthorBookGraphqlApplication.class, args);
}
}
the error is thrown on start:
Field repository in com.author.book.graphql.demo.service.AuthorService required a bean of type 'com.author.book.graphql.demo.repository.AuthorRepository' that could not be found.
Update code as below
Spring will automatically import the beans into the container and inject to dependencies with these annotations.
#Component, #Controller, #Service and #Repository - Helps to define the beans so the container is aware of them and can inject them for you with #Autowired.
#Autowired - Handles only wiring part here.
#Service
public class AuthorService {
#Autowired
private AuthorRepository repository;
public String getAll(){return "XXXXX";}
}
#Repository
public interface AuthorRepository extends CrudRepository<Author, Integer> {}
Before class AuthorRepository, Let's put more annotation #Repository.

Conflict beeween JPA #Entity and Spring #Component/#Resource/#Configurable

I want to Autowire a class which is annotated via JPA #Entity, so i added Spring's #Component/#Resource/#Configurable annotations but it will not allow me to autowire that class.
Is there any other annotation required ?.
Sample is:
#Component
#Entity
#Table
public class Employee{
#Autowired
TestService testService;
...
}
Where class TestService is annotated with #Service .
You can easily do that, make a constructor and pass the injected Service as perameter:
#Component
#Entity
#Table
public class Employee{
Employee(TestService testService){
//Do some work
}
...
}
now caller class..
#Service
public class CallerClass{
#Autowired
TestService testService;
Employee employee =new Employee(testService);
}
You need to use #Configurable
#Entity
#Table
#Configurable
public class Employee{
#Autowired
TestService testService;
...
}
http://docs.spring.io/spring/docs/current/spring-framework-reference/html/aop.html#aop-atconfigurable

Spring autowire before constructor

Hi, I have a class that I want to test. This class has an autowired DAO object this object is been used in a #PostConstruct method, but I want to use the mock and not the real object is there a way. Here is an example:
#Autowired
PersonDao personDao;
//Constructor
public Person()
{
//Do stuff
}
#PostConstruct
void init()
{
//I need it to be a mock
personDao.add(new Person());
}
If you want to use mocked PersonDao you have several choices:
defines PersonDao mock as a Spring bean with primary="true" attribute so that it will have precedence over normal bean
move autowiring to constructor and create Person manually by providing a mock:
PersonDao personDao;
#Autowired
public Person(PersonDao personDao)
{
this.personDao = personDao;
}
then:
new Person(personDaoMock)
and don't rely on Spring.
you can modify private field using ReflectionTestUtils:
ReflectionTestUtils.setField(person, "personDao", mock);

Resources