Reading annotations defined on interfaces and create bean classes using annotation values - spring

I am trying to create http client on the fly from jaxrs annotations provided on the interface for each api.
public #interface RestClient {
String baseUrlKey();
}
#Component
#RestClient(baseUrlKey="NOTIFICATION")
#Path("/notification/")
public interface NotificationClient {
#Path("/")
#POST
#Produces("application/json")
#Consumes("application/json")
public abstract NotificationResponse create(NotificationEntry entry);
}
Now, I am trying to write another class which is trying to find all interfaces annotated with #RestClient. I cant seem to find any solution for this. All application context methods seem to return classes which can be instantiated. Is there any way I can load this interface and create bean instance of apache http client on the fly and register with application context.
Here is the bean initializer class -
public class RestClientBeanProcessor {
private static final Logger LOGGER = LoggerFactory.getLogger(RestClientBeanProcessor.class);
#Autowired
RestTemplate restTemplate;
#Autowired
ApplicationContext applicationContext;
#PostConstruct
private void registerClientBeans() {
Map<String, Object> beans = applicationContext.getBeansWithAnnotation(RestClient.class);
LOGGER.info("Registering client beans for - " + beans);
}
}
My beans object is empty. Spring is unable to tell me list of interfaces asked by my query.

Related

Does spring inject any beans provided in the #Configuration class

If I have a #Configuration class where I have a bean like below, will the dataMap be resolved in the constructor of the DataService class. What type of dependency injection is this? Is it by type because the name for sure doesn't match?
#Bean
public Map<String, List<Data>> data() {
final Map<String, List<Data>> dataMap = new HashMap<>();
readings.put("1", new Data());
return dataMap;
}
and a class
#Service
public class DataService {
private final Map<String, List<Data>> information;
public DataService(Map<String, List<Data>> information) {
this.information = information;
}
}
#Configuration annotation serves as a placeholder to mention that whichever classes annotated with #Configuration are holding the bean definitions!
When Spring application comes up, spring framework will read these definitions and create beans (or simply objects) in IOC (Inversion of control) container These would be Spring managed objects/beans !
To answer your question, it should create a bean and this is a setter based injection!
However, your #Bean must be some user defined or business entity class in ideal scenarios!
Few links for you to refer to:
https://www.codingame.com/playgrounds/2096/playing-around-with-spring-bean-configuration
https://www.linkedin.com/pulse/different-types-dependency-injection-spring-kashif-masood/

What is the best way to inject a singleton service into a JAX-RS/Jersey resource?

For example, what if several resource endpoints need access to some message bus to handle requests? Surely there is some way to register a singleton service class and inject it into the resources when the service class itself is NOT a resource but used by the resources.
All of the examples I've seen with providers or custom HK2 bindings refer to resources.
The closest thing I found to what I'm looking for was with this question:
Trouble creating a simple singleton class in Jersey 2 using built-in Jersey dependency injection
What is the best JAX-RS/Jersey way of doing this?
Note that the programmatic way would be most useful, I'm not using an xml file to configure the server.
If your platform supports EJB, you could use the #Singleton EJB (javax.ejb package, not javax.inject), and inject it on your resources with the #EJB annotation. Singleton EJB have also outofthebox concurrency access control.
On plain Jersey, you can use CDI application context. Declare the service class with an #ApplicationScoped annotation and inject it on your resources with #Inject. CDI will only instantiate one bean.
If you cannot annotate the service class, you can create a method that provides your service implementation an annotate it with #Produces and #ApplicationScoped.
#Produces
#ApplicationScoped
public MyService produceService() {
// instantiate your service client
}
And then use it on your resources, with:
#Inject
private MyService
Answer credit goes to #areus the answer provided here.
However, I'm providing my own answer so that I can share the code.
The Service Bean
#Singleton
public final class MyServiceBean
{
private static final AtomicInteger INSTANCES = new AtomicInteger();
private final AtomicInteger calls = new AtomicInteger();
public MyServiceBean()
{
INSTANCES.incrementAndGet();
}
public String getMessage()
{
return String.format("MyServiceBean{INSTANCES=%d, CALLED=%d}", INSTANCES.get(), calls.incrementAndGet());
}
}
The Resource Class
#Path("/messages")
public final class MyResource
{
#Inject
private MyServiceBean bean;
#GET
#Produces(MediaType.TEXT_PLAIN)
public Response handle()
{
return Response.ok(this.bean.getMessage())
.type(MediaType.TEXT_PLAIN_TYPE)
.build();
}
}
HK2 Binder
public final class MyServiceBeanBinder extends AbstractBinder
{
#Override
protected void configure()
{
bind(MyServiceBean.class).to(MyServiceBean.class).in(Singleton.class);
}
}
Then just register the binder and the resource like so:
final ResourceConfig config = new ResourceConfig();
config.register(MyResource.class);
config.register(new MyServiceBeanBinder());
Starting the server and hitting the resource multiple times yields:
MyServiceBean{INSTANCES=1, CALLED=1}
MyServiceBean{INSTANCES=1, CALLED=2}
MyServiceBean{INSTANCES=1, CALLED=3}
MyServiceBean{INSTANCES=1, CALLED=4}
MyServiceBean{INSTANCES=1, CALLED=5}

Use spring Transactional in a Prototype bean

I would like to use spring transaction management capabilities within a prototype bean. I did the following:
I've used javax.inject.Provider to create my prototype bean.
I've annotated the method of the prototyped bean with the #Transactional annotation.
Is this the right way of doing it?
#Service
public class SomeService {
#Autowired
private Provider<SomePrototype> myPrototypeProvider;
public void execute() {
SomePrototype somePrototype = myPrototypeProvider.get();
somePrototype.someMethod();
}
}
#Component
#Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class SomePrototype {
#Autowired
private SomeSpringBean someSpringBean;
#Autowired
private SomeRepository someRepository;
#Transactional(propagation = Propagation.REQUIRED)
public void someMethod() {
Result result = someSpringBean.doSomething();
someRepository.save(result);
}
}
The initialisation of transaction-scoped bean requires a proxy. Therefore, if we define a transactional bean as prototype, every that bean is requested, a new proxy is created, and that is not efficient.
What is reason behind this requirement (to have transactional prototype bean)

Java 8 and Spring 4 : Use autowiring in interface

Java 8 added a new feature by which we can provide method implementation in interfaces.
Is there any way in Spring 4 by which we can inject beans in the interface which can be used inside the method body?
Below is the sample code
public interface TestWiring{
#Autowired
public Service service;// this is not possible as it would be static.
//Is there any way I can inject any service bean which can be used inside testWiringMethod.
default void testWiringMethod(){
// Call method of service
service.testService();
}
}
This is a bit tricky but it works if you need the dependency inside the interface for whatever requirement.
The idea would be to declare a method that will force the implemented class to provide that dependency you want to autowire.
The bad side of this approach is that if you want to provide too many dependencies the code won't be pretty since you will need one getter for each dependency.
public interface TestWiring {
public Service getService();
default void testWiringMethod(){
getService().testService();
}
}
public class TestClass implements TestWiring {
#Autowire private Service service;
#Override
public Service getService() {
return service;
}
}
You can created Class utils of application context and use it everywhere even not bean class .
you can have code somethins this :
public class ApplicationContextUtil implements ApplicationContextAware {
private static ApplicationContext applicationContext;
#Override
public void setApplicationContext(ApplicationContext context) {
ApplicationContextUtil.applicationContext = context;
}
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
}
and add this to your spring configuration
<bean class="com.example.ApplicationContextUtil" id="applicationContextUtil"/>
now simple to use when you need :
ApplicationContextUtil.getApplicationContext().getBean(SampleBean.class)
this word in web and simple spring app.

Why Spring #Autowired ApplicationContext appContext is null?

I have Spring bean with annotations:
#Named
#Scope("session")
And this bean property:
#Autowired
ApplicationContext appContext;
The Spring configuration file has entry (that works for other anotations/injections):
<context:component-scan base-package="my.package.name" />
Why appContext is null after such code and configuration?
I am trying to get ApplicationContext (to call getBean(...) on it) and this can be quite involved task (judging from other discussions) in previous Spring versions (e.g. one is required to get ServletContext in Spring web application to create ApplicationContext and getting ServletContext can be quite involved task for beans that don't directly access HTTP Request objects). In Spring 3.x, as I understand, simple #Autwired injection can be used. How AppContext can be accessed?
Here the first problem is you are using #Named which is Java EE annotation and as for as I know Spring yet to support Java EE annotations. Hence instead of using #Named try to use Spring annotation #Service, #Component, #Repository etc.
Here is the example for you I have used JSF Managed bean as well to show how to integrate beans.
#ManagedBean(name="myBacking")
#RequestScoped
public class MyBacking {
private String myText;
#ManagedProperty(value="#{mySpring}")
MySpringBean mySpring;
public String getMyText() {
myText = mySpring.getText();
return myText;
}
public void setMyText(String myText) {
this.myText = myText;
}
public MySpringBean getMySpring() {
return mySpring;
}
public void setMySpring(MySpringBean mySpring) {
this.mySpring = mySpring;
}
}
#Service("mySpring")
#Scope("request")
public class MySpringBean {
#Autowired
MySecond mySecond;
public String getText(){
return "Hello KP" + mySecond.appObj();
}
}
#Service
#Scope("request")
public class MySecond {
#Autowired
ApplicationContext applicationContext;
public String appObj(){
MyThrid mythird =(MyThrid)applicationContext.getBean("myThrid");
return "My Second Bean calld "+ mythird.getTxt();
}
}
#Service
public class MyThrid {
public String getTxt(){
return "from thrid Bean";
}
}

Resources