I have worked with Spring and there is a nice feature
BeanPostProcessor where I can do with the bean whatever I want.
But now I am working with Apache aries blueprint (OSGI-based application) and wondering, is there anything similar to BeanPostProcessor in Blueprint? I need to wrap my bean in a proxy. Some interceptors, listeners, or anything that can help me work with beans? I need to add some functionalities to the beans during runtime (cache for example) and want to avoid changing the existing code.
Investigated the blueprint codebase, beans are created in BeanRecipe class in the blueprint, but I haven't found anything where I can inject my code for bean creation
I think proxy suits the best for such a purpose. Also, I am open to any suggestions from you. Thanks!
Related
I have an application with a complex mix of #Imports and #ComponentScans.
There is a class marked as #Component that I expected not to be added to the application context, but it is, and I want to climb back the scan chain to find out why is that bean registered.
Is there any easy way I can do that e.g. by using Spring Tools 4 Eclipse's plug-in features or maybe programmatically? Googling keywords led to no result.
Enable the actuator and look at the beans endpoint (/actuator/beans).
The resource property tells you, where this bean might have been included.
I am looking for a a way to do runtime injection of a bean in Quarkus. I realize this might be a bit on an unorthodox approach for quarkus, and something on an anti-pattern, so no need to point that out, I am fully aware :)
What I am looking for is a way to construct a bean during runtime, and having any annotated properties injected from the Quarkus context.
In Spring Boot I would get the application context by having a bean initialized normally by spring boot, using the ApplicationContextAware interface to inject the application context. I would then use that as a factory by calling ApplicationContext.getAutowireCapableBeanFactory() to get the auto-wire factory and using the autowireBean method on the factory to autowire my beans during runtime. I am wondering if something similar is possible in Quarkus?
This is similar to this question.
How to programmatically inject a Java CDI managed bean into a local variable in a (static) method
javax.enterprise.inject.spi.CDI.current().getBeanManager().select(C.class).get()
To make sure that the bean class is manged use the io.quarkus.arc.Unremovable annotation.
I am studying for the Spring Core certification and I have following doubt about this question:
What is meant by “container” and how do you create one?
I know that the Spring container is at the core of the Spring Framework. The container will create the objects, wire them together, configure them, and manage their complete lifecycle from creation till destruction. The Spring container uses dependency injection (DI) to manage the components that make up an application. These objects are called Spring Beans which we will discuss in next chapter.
And I know that there exist 2 containers:
Spring BeanFactory Container: This is the simplest container providing basic support for DI and defined by the org.springframework.beans.factory.BeanFactory interface. The BeanFactory and related interfaces, such as BeanFactoryAware, InitializingBean, DisposableBean, are still present in Spring for the purposes of backward compatibility with the large number of third-party frameworks that integrate with Spring.
Spring ApplicationContext Container: This container adds more enterprise-specific functionality such as the ability to resolve textual messages from a properties file and the ability to publish application events to interested event listeners. This container is defined by the org.springframework.context.ApplicationContext interface.
Ok...this is pretty clear for me but what is the correct answer about How to create a container?
I think that it is automatically created by the Spring when it reads the configuration class or the XML configuration file.
Or not? What am I missing?
In short, "The Container" is a Spring instance in charge of managing the lifecycle of your beans.
To create one, basically, you should do something like
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("/application-context.xml");
Remember replacing /application-context.xml by the file where you define your own Spring beans.
Take a look at http://www.springbyexample.org/examples/intro-to-ioc-creating-a-spring-application.html
You could also substitute the xml by a configuration class. On that case you should have something like this:
#Configuration
public class Myconfig{
#Bean
public MyBean myBean(){
return new MyBean();
}
}
For this, take a look at http://www.tutorialspoint.com/spring/spring_java_based_configuration.htm
I am reading on JSF and I have a question about managed beans. Does "managed" only refer to the fact that the JSF implementation instantiate and manage their lifecycle? And the new thing now is to use CDI that is a different implementation that handles the instantiation and their lifecycle? Is that what it means by managed?
Is CDI an implementation capable of instantiating beans and manage them outside JSF, is that why it is better? If so, what was the option outside of JSF before? Did each container or implementation had their own way of managing the beans? And is CDI the thing that unifies this?
Before JSF2 annotations, in JSF1 the developers have to register the beans as <managed-bean> in faces-config.xml. The support is still there in JSF2, but it became optional and could in some cirsumstances be the only way if you want to override the annotations of a managed bean which is packaged in a 3rd party JAR.
Long before JSF and CDI, in plain JSP/Servlet, developers have to manually create and manage beans itself by explicitly instantiating them and explicitly placing them in the request, session or application scopes by
request.setAttribute("requestScopedBean", requestScopedBean);
request.getSession().setAttribute("sessionScopedBean", sessionScopedBean);
getServletContext().setAttribute("applicationScopedBean", applicationScopedBean);
(prechecks omitted, the bean is of course only placed in the scope if it isn't in the scope yet, else it will be reused)
Note that the above is exactly what JSF does "under the covers".
Then various MVC frameworks were invented to abstract this away by declaring the beans in XML file or even by annotations. Every MVC framework had its own way of managing beans. Then there was Spring, which tried to unify it by providing a framework-independent approach. Then there was Java EE 6 CDI which standardized it.
This all was always been container-independent. It's framework-specific.
I'm currently migrating a JBoss service class from AS5.1 to AS6 (not going to AS7 for a variety of reasons).
For AS5.1, the service implements a {serviceName}MBean and has a jboss-service.xml with attribute values. It's packaged in a jboss-sar, which is packaged in an EAR to be deployed. When deployed, the service fields are populated with the values from jboss-service.xml, and the service is automatically registered into JMX.
I would like to achieve the same thing using AS6, but would like the service to support CDI - so I'd like its new #Inject injection points to be satisfied. I need these to be satisfied in the object registered with JMX, so that methods called via JMX can reference injected fields, but I'm struggling to achieve this.
I've had to package the service in a jar, instead of a jboss-sar, for classloader reasons, but let's say it's otherwise unchanged. When deployed to AS6, all works as before - service goes into JMX, values from XML propagate to the object. However, the instance created does not have its CDI injection points satisfied, and neither does the object registered in JMX.
If I annotate the service class with #Startup and #javax.ejb.Singleton, but keep its interface and the jboss-service.xml, the object registered into JMX still does not have its CDI injection points satisfied. However if I programmattically deregister that bean, and re-register the instance in a #PostConstruct method, then the bean in JMX DOES have its injection points satisfied. However that bean no longer has the values specified in the jboss-service.xml.
So how can I get the best of both worlds? CDI and the usual JBoss service behaviour? What is the correct way to implement a JBoss service with CDI? I've been unable to find documentation on this. Hope someone can help.
Thanks,
Ben
As a worst-case fallback, you should be able to use the CDI extension API to get your service to be injected. I don't think you would need to write a fully-fledged extension, but if you have an initialisation hook in the service object, you can do this (lifted with minor editing from the docs, not compiled or tested):
public static <T> void inject(T object) {
BeanManager beanManager = (BeanManager)new InitialContext().lookup("java:comp/BeanManager");
AnnotatedType<T> type = beanManager.createAnnotatedType(object.getClass());
InjectionTarget<T> it = beanManager.createInjectionTarget(type);
CreationalContext ctx = beanManager.createCreationalContext(null);
it.inject(object, ctx);
it.postConstruct(object);
}
Basically, any object to that method will get injected. All the usual CDI annotations should work. Hopefully.
As mentioned in the comments above, it seems Tom's right - there's no 'nice' way of created a CDIed, JMX bean in one go, you either have to put your JMX bean in CDI, as is suggested above, or put you CDIed bean into JMX. We tried the former, but it appears the BeanManager isn't bound to JNDI at the point the service starts up.
So instead we went with CDI bean -> JMX. We're creating the services as Singleton EJBs, so their injection points are satisfied, and they then get registered/unregistered to JMX in their PostConstruct/PreDestroy methods, using German Escobar's excellent CDI portable extension (germanescobar.net/2010/01/cdi-portable-extension-jmx.html, community.jboss.org/thread/148750 is also helpful).
May try to use ApplicationScoped beans and get them to start by observing a ContainerInitialized(?) event, however, as we don't need all the features of an EJB. Haven't tried that yet, mind...