i want to create the non-web spring boot application. But i am getting following error
#SpringBootApplication
public class TaskApplication implements CommandLineRunner {
#Autowired
TaskService taskService;
public static void main(String[] args) {
SpringApplication.run(TaskApplication.class, args);
}
#Override
public void run(String... args) throws Exception {
taskService.print();
}
}
public interface TaskService {
public void print();
}
public class TaskServiceImpl implements TaskService {
#Override
public void print() {
System.out.println("sam");
}
}
properties:
spring.datasource.url=jdbc:mysql://localhost:3306/demo?verifyServerCertificate=false&useSSL=false&requireSSL=false&allowPublicKeyRetrieval=true
spring.datasource.username=root
spring.datasource.password=root#123
spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver
spring.jpa.show-sql=true
spring.jpa.hibernate.dialect=org.hibernate.dialect.MySQLDialect
spring.main.allow-bean-definition-overriding=true
##spring.jpa.hibernate.ddl-auto=update
error
***************************
APPLICATION FAILED TO START
***************************
Description:
Field taskService in com.example.task.TaskApplication required a bean of type 'com.example.task.service.TaskService' that could not be found.
The injection point has the following annotations:
- #org.springframework.beans.factory.annotation.Autowired(required=true)
Action:
Consider defining a bean of type 'com.example.task.service.TaskService' in your configuration.
#M. Deinum already explained in comments. You need to mark classes with #Service or #Component annotation to create the spring bean and autowired in main methods.
// mark it with service annotation.
#Service
public class TaskServiceImpl implements TaskService {
#Override
public void print() {
System.out.println("sam");
}
}
To understand why those annotation is necessary here please visit this link : #Component vs #Repository and #Service in Spring
you need to configure #EnableAutoConfiguration on main class and your TaskService must be annotated with #Service
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 declared a service in package service like:
import a.b.c.d.soapapim.SoapApimMiddlewareService;
#Service
#EnableDefaultExceptionHandling
public class MyService{
private final SoapApimMiddlewareService myService;
public MyService(SoapApimMiddlewareService myService){
this.myService = myService;
}
public Response pullEvents(numEvents){
myService.pullEvents(numEvents);
}
}
SoapApimMiddlewareService is a dependency in my spring boot project declared in my project's pom.xml in the package a.b.c.d.soapapim
in my application.java:
#ComponentScan({"a.b.c.d.soapapim", "service", "scheduler"})
SpringBootApplication
#EnableScheduling
public class Application implements WebMvcConfigurer {ยด
public static void main(String[] args){
SpringApplication app = new SpringApplication(Application.class);
app.setRegisterShutdownHook(false);
app.run(args);
}
}
I also have a scheduler:
#Component
public class Scheduler {
private MyService myService;
#Scheduled(fixedRate = 1200)
public void myScheduledTask(){
myService.pullEvents(1);
}
}
I am getting the following error:
UnsatisfiedDependencyException: Error creating bean with name MyService No qualifying bean of type 'a.b.c.d.soapapim.SoapApimMiddlewareService'
I can't annotate that class because its a dependency I don't have access to. I just declare it as a dependency on the pom.xml of my project.
How can I get this bean into the context of my spring boot application?
You can declare it as spring bean using #Bean annotation in config class
#Bean
public SoapApimMiddlewareService soapApimMiddlewareService() {
return new SoapApimMiddlewareService():
}
May I annotate a simple pojo by #Component ?
It is because IntelliJ says :
could not autowire, no beans found
Thanks
Of course you can annotate pojo with #Component, and then you can autowire it within another pojo also annotated with #Component e.g:
#Component
public class Computer {
#Autowired
Procesor procesor;
public void printName() {
System.out.println("486DX");
}
}
#Component
public class Procesor {
}
#SpringBootApplication
public class SpringOneApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(SpringOneApplication.class, args);
Computer computer = (Computer) context.getBean("computer");
computer.printName();
}
}
I want to implement custom repo with Spring data mongodb.
Application.java:
#SpringBootApplication
public class Application implements CommandLineRunner{
#Autowired
private CustomerRepositoryCustom repo;
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#Override
public void run(String... args) throws Exception {
System.out.println(this.repo.customMethod());
}
}
My custom repository CustomerRepositoryCustom.java
public interface CustomerRepositoryCustom {
List<Customer> customMethod();
}
Custom implementation CustomCustomerRepositoryImpl.java
public class CustomCustomerRepositoryImpl implements CustomerRepositoryCustom {
#Autowired
private MongoTemplate mongoTemplate;
#Override
public List<Customer> customMethod() {
return this.mongoTemplate.findAll(Customer.class);
}
}
Code Structure
-Application.java
dal
model...
repository
-CustomCustomerRepositoryImpl.java
-CustomerRepositoryCustom.java
When I try to build it, i get an error:
**Description**:
Field repo in socketApp.Application required a bean of type 'socketApp.dal.repository.CustomerRepositoryCustom' that could not be found.
**Action**:
Consider defining a bean of type 'socketApp.dal.repository.CustomerRepositoryCustom' in your configuration.
You have to make Spring aware of your repository. For a Spring Boot application this is typically done by adding this annotation to your application ...
#EnableMongoRepositories("com.package.path.to.repository")
.... thereby telling Spring Boot where to look for Mongo repositories and then let your interface extend org.springframework.data.mongodb.repository.MongoRepository.
For example:
public interface CustomerRepositoryCustom extends MongoRepository {
List<Customer> customMethod();
}
Alternatively, you could annotate your CustomCustomerRepositoryImpl with #Repository and ensure that it is in a package which is scanned by Spring Boot.
I wonder why the field injection works in the #SpringBootApplication class and the constructor injection does not.
My ApplicationTypeBean is working as expected but when I want to have a constructor injection of CustomTypeService I receive this exception:
Failed to instantiate [at.eurotours.ThirdPartyGlobalAndCustomTypesApplication$$EnhancerBySpringCGLIB$$2a56ce70]: No default constructor found; nested exception is java.lang.NoSuchMethodException: at.eurotours.ThirdPartyGlobalAndCustomTypesApplication$$EnhancerBySpringCGLIB$$2a56ce70.<init>()
Is there any reason why it does not work at #SpringBootApplication class?
My SpringBootApplication class:
#SpringBootApplication
public class ThirdPartyGlobalAndCustomTypesApplication implements CommandLineRunner{
#Autowired
ApplicationTypeBean applicationTypeBean;
private final CustomTypeService customTypeService;
#Autowired
public ThirdPartyGlobalAndCustomTypesApplication(CustomTypeService customTypeService) {
this.customTypeService = customTypeService;
}
#Override
public void run(String... args) throws Exception {
System.out.println(applicationTypeBean.getType());
customTypeService.process();
}
public static void main(String[] args) {
SpringApplication.run(ThirdPartyGlobalAndCustomTypesApplication.class, args);
}
public CustomTypeService getCustomTypeService() {
return customTypeService;
}
My #Service class:
#Service
public class CustomTypeService {
public void process(){
System.out.println("CustomType");
}
}
My #Component class:
#Component
#ConfigurationProperties("application.type")
public class ApplicationTypeBean {
private String type;
SpringBootApplication is a meta annotation that:
// Other annotations
#Configuration
#EnableAutoConfiguration
#ComponentScan
public #interface SpringBootApplication { ... }
So baiscally, your ThirdPartyGlobalAndCustomTypesApplication is also a Spring Configuration class. As Configuration's javadoc states:
#Configuration is meta-annotated with #Component, therefore
#Configuration classes are candidates for component scanning
(typically using Spring XML's element) and
therefore may also take advantage of #Autowired/#Inject at the field
and method level (but not at the constructor level).
So you can't use constructor injection for Configuration classes. Apparently it's going to be fixed in 4.3 release, based on this answer and this jira ticket.