Scan of fiegn client present in other package jar - spring-boot

We have one custom jar which has fiegn client in com.pack.mav.tru.client package of jar.
Now this jar is imported using pom.xml in our spring boot application.
In this main application we added the component scan with base packes and also that jar package.
Yet we see null object, when we autowire that fiegn client in that jar one class.
What we are missing, please help.
package com.pack.mav.tru.client;
#FeignClient(name = "user")
public interface UserClient {
public void getUser(#PathVariable String id);
}
package com.pack.mav.tru.service;
public class ProductService {
#Autowired
userClient userclient;
public void method(string id) {
userClient.getuser(id); ---> Here userClient is null
}
The above classes are present in one jar
We import same jar in our main spring application and added scan in main application class as below.
#ComponentScan(basePackages = { "com.mav.pack.*", "com.pack.mav.tru.client.*"})

Related

Autowire Bean and application.yml file in another jar file

I am experimenting with spring boot multi module projects for my understanding.
My Over All Goal is :
1.Build Spring boot project as independent jar and utilise it on another project.
2.Autowire Bean properties inside jar as per new project. Make it independent.
Things I have done so far.
Project providerModule1
Declare a Service(MyService).
#Component
public class MyService {
#Autowired
ServiceProperties serviceProperties;
public String getInfoFromProperties() {
return serviceProperties.toString();
}
}
Create a bean called ServiceProperties that will be used in to MyService.
package com.demo.multimodule.providerModule1.util;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import lombok.Data;
#Component
#Data
public class ServiceProperties {
#Value("${default.userName}")
private String name;
#Value("${default.email}")
private String email;
#Value("${default.age}")
private String age;
}
Load the bean ServiceProperties by reading propeties from yml file.
default:
userName: userName1
email: default#email.com
age: 18
Build the Project ProviderModule1 using maven plugin
Project ParentProjectApplication
5. Load the maven dependency.
<dependency>
<groupId>com.demo.multimodule</groupId>
<artifactId>providerModule1</artifactId>
<version>0.0.1-SNAPSHOT</version>
<classifier>app-to-import</classifier>
</dependency>
Autowire the MyService from project providerModule1
package com.multimodule.demo.parentProject.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.demo.multimodule.providerModule1.service.MyService;
#Service
public class HomeService {
#Autowired
private MyService myService;
public String getHomeInfo() {
return "Home Info from Home service : "+myService.getInfoFromProperties();
}
}
Initially myservice was not getting loaded .Hence I added this step to main application class:
#SpringBootApplication(scanBasePackages= {"com.demo.multimodule.providerModule1.service",
"com.demo.multimodule.providerModule1.util"})
public class ParentProjectApplication {
}
Question 1 : Is this the only way using which I can autowire bean from a jar. If there is another way let me know.
I executed the Project ParentProjectApplication and it seem to work as expected.
Question 2 : Is it possible to autowire new yml property from Project ParentProjectApplication and make ServiceProperties bean of project ProviderModule1 utilise it.
you can try spring.factory to create beans.
refer the link below
https://docs.spring.io/spring-boot/docs/2.0.0.M3/reference/html/boot-features-developing-auto-configuration.html

Spring Boot: autowire beans from library project

I'm struggling to autowire beans from my custom library, imported with gradle.
after reading couple of similar topics I am still unable to find solution.
I have a Spring Boot project that depends on another project (my custom library with Components, Repositories etc...). This library is a Spring non-runnable jar, that consists primarily of domain Entities and Repositories. It doesn't have runnable Application.class and any properties...
When I start the application I can see that My 'CustomUserService' bean (from the library) is trying to be initialized, but the bean autowired in it failed to load (interface UserRepository)...
Error:
Parameter 0 of constructor in
com.myProject.customLibrary.configuration.CustomUserDetailsService
required a bean of type
'com.myProject.customLibrary.configuration.UserRepository' that could not
be found.
I've even tried to set 'Order', to load it explicitly (with scanBasePackageClasses), scan with packages and marker classes, add additional EnableJPARepository annotation but nothing works...
Code example (packages names were changed for simplicity)
package runnableProject.application;
import runnableProject.application.configuration.ServerConfigurationReference.class
import com.myProject.customLibrary.SharedReference.class
//#SpringBootApplication(scanBasePackages = {"com.myProject.customLibrary", "runnableProject.configuration"})
//#EnableJpaRepositories("com.myProject.customLibrary")
#SpringBootApplication(scanBasePackageClasses = {SharedReference.class, ServerConfigurationReference.class})
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
Classes from the library:
package com.myProject.customLibrary.configuration;
import com.myProject.customLibrary.configuration.UserRepository.class;
#Service
public class CustomUserDetailsService implements UserDetailsService {
private UserRepository userRepository;
#Autowired
public CustomUserDetailsService(UserRepository userRepository) {
this.userRepository = userRepository;
}
...
package myProject.customLibrary.configuration;
#Repository
public interface UserRepository extends CustomRepository<User> {
User findByLoginAndStatus(String var1, Status var2);
...
}
Just found the solution.
Instead of defining base packages to scan from separate library, I've just created configuration class inside this library with whole bunch of annotation and imported it to my main MyApplication.class:
package runnableProject.application;
import com.myProject.customLibrary.configuration.SharedConfigurationReference.class
#SpringBootApplication
#Import(SharedConfigurationReference.class)
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
package com.myProject.customLibrary.configuration;
#Configuration
#ComponentScan("com.myProject.customLibrary.configuration")
#EnableJpaRepositories("com.myProject.customLibrary.configuration.repository")
#EntityScan("com.myProject.customLibrary.configuration.domain")
public class SharedConfigurationReference {}
You can create a folder called 'META-INF' in the 'resources' folder of your library and add a file called 'spring.factories' with the content org.springframework.boot.autoconfigure.EnableAutoConfiguration=<fully_qualified_name_of_configuration_file>. This will autoconfigure your library.
The accepted answer is too cumbersome. What you would need to do is implement your own custom auto-configuration in your library jar so that it is picked up in the classpath scan in the main application. More details here

Spring boot find autowired on another package

I'm developing a Spring Boot application which uses some Spring Data Repository interfaces:
package test;
#SpringBootApplication
public class Application implements CommandLineRunner {
#Autowired
private BookRepository repository;
. . .
}
I can see that the BookRepository interface (which follows here) can only be injected if it's in the same package as the Application class:
package test;
public interface BookRepository extends MongoRepository<Book, String> {
public Book findByTitle(String title);
public List<Book> findByType(String type);
public List<Book> findByAuthor(String author);
}
Is there any Spring Boot annotation I can apply on my classes to be able to find the BookRepository in another package ?
Use a Spring #ComponentScan annotation alongside the SpringBoot #SpringBootApplication and configure a custom base package (you can either specify a list of package names or a list of classes whose package will be used), so for example
#SpringBootApplication
#ComponentScan(basePackages = {"otherpackage", "..."})
public class Application
or
#SpringBootApplication
#ComponentScan(basePackageClasses = {otherpackage.MyClass.class, ...})
public class Application
or since Spring 1.3.0 (Dec. 2016), you can directly write:
#SpringBootApplication(scanBasePackageClasses = {otherpackage.MyClass.class, ...})
public class Application
Note that component scan will find classes inside and below the given packages.
Good to verify the scopes of classes kept in different packages by using #ComponentScan annotation in Spring boot startup custom class.
Also add #Component in modal classes being used to allow framework accessing the classes.
Example is kept at
http://www.javarticles.com/2016/01/spring-componentscan-annotation-example.html

Spring Data JPA repositories not being auto-created with CommandLineRunner

I am trying to write a simple Spring Data JPA app for Spring Boot in Groovy. I followed the getting started guide and did some basic transformation to make it work with Groovy and the Spring Boot CLI.
I am running the code with the Spring Boot CLI (v1.1.8):
spring run app.groovy
This results in the error:
NoSuchBeanDefinitionException: No qualifying bean of type [hello.CustomerRepository] is defined
Does anyone have an idea why the Repository is not getting created automatically? I feel like I must be missing something simple. Here is the app.groovy file containing all of the code:
package hello
#Grab("spring-boot-starter-data-jpa")
#Grab("h2")
import java.util.List
import javax.persistence.*
import org.springframework.boot.SpringApplication
import org.springframework.boot.autoconfigure.EnableAutoConfiguration
import org.springframework.context.ConfigurableApplicationContext
import org.springframework.context.annotation.Configuration
import org.springframework.data.repository.CrudRepository
#Entity
class Customer {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
long id
String name
Customer() {}
Customer(String name) {
this.name = name
}
}
interface CustomerRepository extends CrudRepository<Customer, Long> {
List<Customer> findByName(String name)
}
#Configuration
#EnableAutoConfiguration
class Application implements CommandLineRunner {
#Autowired
ConfigurableApplicationContext context
void run(String[] args) {
CustomerRepository repository = context.getBean(CustomerRepository.class)
repository.save(new Customer("Jack", "Bauer"))
}
}
A Groovy CLI app can only scan for JPA repositories if you give it actual classes (i.e. not the .groovy scripts). You can build a jar file and run that, and it should work:
$ spring jar app.jar app.groovy
$ java -jar app.jar

How to autowire #service from external Jar in Spring

I am developing two spring based application(Ex app1 and app2) fully on Java configuration with Maven and no XML config.
Through Maven -WAR plugin , I have created Jar reference of app2 and using mvn install:install file I have binded the app2 jar with app1.
app2 - Its used to fetch inforamtion from data source.
I have autowired the app2 serive in app1 implementation class to fetch the details which was annotated with #Service in app2 application.
My first doubt is:
Both app1 and app2 have separate AppConfig.java file.Is it possible to simply autowiring one of the #Service which is availble in Jar format or else I need to define or import App2's AppConfig java file into App1's AppConfig.jave file.
I have tried with the simple autowired the external JAR #Service class and ended with error.
Kindly help me on what needs to be done to autowire external Jar's #Service to the
implementation class.
Below is my App1 repository class
#Repository
public class VehicleRepository {
#Autowired
VehicleService vehicleservice;
public Map<String, item> getAllTypes(String type) {
Vehicke vehicle = vehicleservice.getAllVehicle(type);
// handle response here...
} catch (Exception ex) {
// handle exception here
} finally {
}
return vehicleDetails;
}
}
VehicleService is available in external Jar.
VehicleService Class:
#Service
public class VehicleService {
public VehicleService() {
}
#Autowired
PortRepository portRepository;
#Autowired
MessageSource messageSource;
public Vehicle getAllVehicles(String type) {
List<Vehicle> cehicles = portRepository.getPorts();
return vehicle;
}
Let's make it simple.
Your App1 depends on App2.
So you use #Import(App2Config.class) class App1Config {}, that's it.
And by the way, instead of tricks with 'mvn install:install file' you can just use parent pom.xml with modules app1 and app2, and declare dependency of module app1 on module app2 in pom.xml <dependencies> section. You then run 'mvn install' to build your project.
See an example here: http://books.sonatype.com/mvnex-book/reference/multimodule.html

Resources