I'm just started to look at Java EE but I'm struggling to understand what callbacks are exactly and what they are used for.
Does anyone have a clear explanation of what they are? I've looked around the site but been unable to find much information.
The Formal Definition
Callback is a mechanism by which life cycle of an enterprise bean can be intercepted.
A Practical Example
I think a single example will help show off the usefulness of these callback annotations. Let's take a look at the #PreDestroy callback. From the JBoss docs on EJB, we can see that:
PreDestroy - is invoked when the bean is removed from the pool or destroyed.
And you've got a Bean that has some kind of File Resource. You want to ensure that when the Bean is destroyed, that file lock goes with it. Well, we know that it's "risky" practise to wait for the Garbage Collector to handle these things for us; we don't know when it's going to run.
But what we can do is put in place some logic that is called when the bean is removed.
#PreDestroy
public void cleanUp() {
// Clean up your FileOutputStreams etc.
}
In your bean, it's very clear that this method is executed when the bean is destroyed and it requires no extra code from the outside. This ensures that your resources are cleaned up, as and when the bean is destroyed.
Callbacks are your primary opportunity to execute custom code at specific points in the EJB (or the container's lifecycle).
So take for example, you want to initialize specific fields or components
inside the EJB,
after the EJB has been instantiated, but
before it starts to service requests
You'll implement the #PostConstruct callback method. A method annotated with this is an advertisement to the JavaEE runtime that that method must be run immediately after an instance of that class has been created. A common use of this annotation is to instamtiate class-level variables or to prepare shared resources.
The JavaEE specification has designated several annotations such as this one, as lifecycle callbacks. What this means is that at startup, the container knows to scan the deployment kit for artifacts that implement any of the available callbacks. In doing so, it knows to notify the interested components (EJBs, CDI components , JAX-WS bean implementations) of specific events, or call specific methods when...specific actions occur in the app server.
The callback mechanism is in itself an implementation of the Callback pattern (or event-driven programming if you're coming from a UI programming world)
Further Reading:
Oracle's intro to lifecycle callbacks
Related
I have the following design. When a client makes a request to the server, the server creates a state that holds all sorts of info. There are various stateless and stateful beans which need to read and write to this state. Refer to this unprofessional diagram:
The ComputationCycle class is where the processing starts and works by phases. During each phase it calls upon other Manager classes (which behave like utility classes) to help in the computation (diagram shows only for 1 phase). The state is being read and written to both from the CC class and the managers, both are stateless.
State holds Employee, Department and Car classes (in some irrelevant data structure) which are stateful. These classes can also call the Manager classes. This is done by a simple #Inject Manager1. The same way CC uses managers.
My problem is how to access the stateful state (and its contained classes) from the stateless classes (and from the Car, Department and Employee classes too, although I think solving one will solve the other). I can't inject a stateful bean into a stateless bean. So after the client makes a request and the computation cycle starts, how do I access the state related to this request?
One solution is to pass the state to every method in the stateless classes, but this is really cumbersome and bloaty because all methods will have an "idiotic" State argument everywhere.
How can I make this design work the way I want it to?
I can't inject a stateful bean into a stateless bean.
You can absolutely inject dependencies this way.
If the stateful bean is #RequestScoped, any call into the stateless bean on that thread that hits a CDI injected contextual reference (iow proxy) will find its way to the right instance of the stateful bean.
As long as you use CDI, you don't need to trouble yourself with trying to stash things away in your own threadlocals.
Buyer beware, ThreadLocal will possibly do what you're wanting, along with a static accessor. However, this class is prone to causing memory leaks if you are not extremely careful to remove each entry at the end of the request. In addition, you seem to be using EJB; I assume they are all in the same JRE. I use ThreadLocal quite a bit in similar situations, and I've had no problems. I use SerletContextListener's to null the static reference to the ThreadLocal when the context shuts down, although that has been problematic on some older Web app servers, so I make sure the ThreadLocal exists before attempting to use it.
EJB can "talk" to each other across servers. It sounds local all your EJB are running in the same context.
Create a class that holds your state.
Extend ThreadLocal--you can do this anonymously--and override initialValue() to return a new instance of your class.
Create a utility class to hold the ThreadLocal as a static field. Don't make it final Create static fetch and remove methods that call ThreadLocal.get() and remove(). Create a static destroy() method that is called when your context shuts down--see ServletContextListener.
I am currently having lots of trouble with iPojo leaks due to constructed instances that we forget to dispose. I see this as an inevitable drawback of using imperative instantiation using the ipojo Factory technique: basically you say when you need your service by calling factory.createComponentInstance(config), so you have the responsibility to say when you are done with it. This forces me to keep two references, one for the service that I want to consume, but also a second one of the iPojo ComponentInstance so that when the consumer is done, it can call componentInstance.dispose(). If not, there's a leak
Is there a more declarative way to do this where the consumer doesn't need to handle the lifecycle of the iPojo service and its instance?
To simplify my usecase, imagine that there's a UI with a button in it and every time the button is pressed, i need a new, unique instance of an iPojo service. Ideally, the instance would be GC'd when it goes out of scope, without the consumer having to do anything
Maybe my mistake is using services as instances, but I have three reasons to use a service instead of a normal class and calling new.
The service impl should be substitutable
The consumer should depend on an interface, not an implementation/provider, not only because of #1 but also because of tons more transitive dependencies pulled when depending on a concrete impl
The service impl has some dependencies itself that I'm hoping will be injected by iPojo (dependency injection).
As a second request, does anyone know of any opensource, real (i.e not dummy, demo) projects using iPojo that I can use as example of good usage of iPojo?
Instead of creating a component instance, you probably should use a custom 'creation strategy'. So you will have only one component instance, but with several 'implementation' instances (service objects) managed. You decide when these objects are created and disposed. More information on http://felix.apache.org/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-userguide/describing-components/providing-osgi-services.html#service-serving-object-creation.
About a project using iPOJO, you can have a look to Wisdom Framework, which relies on iPOJO: http://wisdom-framework.org (code available there: github.com/wisdom-framework/wisdom/)
At work and online I keep hearing the term "proxy" with respect to enterprise Java development. For example, metrics-spring uses this phrase:
This module does the following things:
Creates metrics and proxies beans which contain methods annotated with
#Timed, #Metered, #ExceptionMetered, and #Counted [emphasis mine]
I'm unfamiliar with a lot of the language in the Java ecosystem of frameworks and libraries. I feel like I have a good understanding of what a bean is, but I'm still not clear about how one would proxy a bean.
What does it mean to proxy a bean?
Typically, you have a bean like
Bean bean = new Bean(); // actually created by the context
With this, you can do anything that the Bean class declares as behavior (invoke its methods).
There are times where it would be nice if you could, for example, track how long a method invocation takes.
You could do
long start = .. // get start time
bean.invoke();
long end = .. // get end time
// end - start
But doing this for each method invocation sucks. So, instead, patterns, architectures, and styles like Aspect Oriented Programming exist.
Instead of the Bean above, you'd have
Bean bean = new TimingBean(new Bean()); // again done by the context
where the TimingBean is a proxy type that extends and implements all the types that Bean extends and implements. For all intents and purposes it is a Bean, but it adds a bunch of additional behavior before delegating each invocation to the Bean object. In this case, it would track how long each of Bean's method's took to execute.
Basic Spring uses JDK proxies and CGLIB proxies. Here are some differences between them.
It uses this for its scheduling and asynchronous invocations. It uses it for transactional support with databases. It uses it for caching. It even uses it for its Java based container configuration.
Proxying means that your client code thinks it's talking to one bean, but a proxy is really doing the listening and responding.
This has been true since early distributed client/server computing models like CORBA. A client would interact with an interface type as if it existed in their memory space, but they were really talking to a proxy that would handle all the messy details around marshalling request data into a request, communicating over the network to the remote object running on a server, and unmarshalling the response back to the client.
Spring uses this model for remoting. It also forms the basis for its aspect oriented programming model. Your code thinks it's dealing with a particular interface; Spring can weave in advice before, after, or around that instance and perform cross cutting operations like logging, transaction management, etc. on your behalf.
Some frameworks rely on a mechanism called instrumentation, which in short means to build a proxy of a given compiled bytecode, adding some code to it in some places we judge useful. This would implement many kinds of tasks, between them for example, adding a kind of profiling to a spring bean, as this library claims to do.
The Spring engine returns heavily instrumented proxies of every managed bean it offers - this way, you can use Spring declarative transaction handling, for instance. You would write "naive" daos without an actual connection handling, and "naive" service classes using the daos without an actual transaction handling - the instrumented proxies will include the boilerplate code with the connection instantiation, commits, rollbacks...
I hope this is of any help
Please pardon this Spring beginner question. I am reading chapter 4 of first edition and being introduced to both call-back method and Bean post processor.
Now I am just getting confused about the two, it seems like they both do sth. when the bean instance is created, so how can I differentiate the two? Maybe an example would be good?
My personal understanding is, if we have to find a difference, then call-back method is initiated when the bean gets actually created, the Bean post processor gets called slightly after the creation of the bean?Also, I think the diference might also be that initalization call-back method focus on one bean only while Beanpost procsso will pocess all the bean instances one by one?
Also, could anybody help me further explain the difference by comaring and contrasting JSR250 annotation #PreDestroy and #PostConstruct with the two concepts above?
Thank you very much for helping!
It's been a while since I've used either of these, but I think the callback method and #PostConstruct methods you are referring to are the same thing. But to answer your question, the difference....
1) The #PostConstruct (or afterPropertiesSet) method is a method internal to a specific class that will be called after a bean is instantiated. This is really where you put type-specific actions.
2) The BeanPostProcessor will touch all Spring beans. So here's where you can put cross-cutting functionality, not necessarily class-specific.
A small example... say I have a small address book application for keeping track of my friends and their addresses. If I have some crazy bug I can't track down, I might use a BeanPostProcessor to wrap all my Spring beans with some logging, such as "now invoking Address.getStreet()..., now invoking Address.getCity()...".
Now I might use a #PostConstruct method in Address to verify and look up zip codes against some web service for addresses where I only have city/state.
Now, I might not actually have one of my domain objects hitting a web service in reality, but the idea is to illustrate that a #PostConstruct can handle class specific stuff and a BeanPostProcessor can take care of things that span multiple classes.
Also it's worth noting, that BeanPostProcessor has two methods to override: postProcessBeforeInitialization and postProcessAfterInitialization, which will let you decide what to run before and after the bean's #PostConstruct method.
Bean post processors interface has two callback methods: 1. PostProcessBeforeInitialization and PostProcessAfterInitialization.
PostProcessBeforeInitialization method is invoked just before calling your init-method or afterPropertySet method of the bean.
PostProcessAfterInitialization method is just called after just after the initialization of bean completed.
Bean Post Processors gives chance to do something before and after initialization of bean.
The SessionContext.getBusinessObject() is described in the docs as follows,
Obtain an object that can be used to invoke the current bean through the given business interface.
Parameters:
businessInterface - One of the local business interfaces or remote business interfaces for this session bean.
Returns:
The business object corresponding to the given business interface.
Can't I use the 'this' keyword in Java instead, to accomplish the same ? How are these different ?
The motivation here is that most EJB implementations work on proxies. You wouldn't be too far off in thinking of it as old-school AOP. The business interface is implemented by the EJB container, quite often via a simple java.lang.reflect.Proxy, and this object is handed to everyone in the system who asks for the ejb via #EJB or JNDI lookup.
The proxy is hooked up to the container and all calls on it go directly to the container who will preform security checks, start/stop/suspend transactions, invoke interceptors, etc. etc. and then finally delegate the call to the bean instance -- and of course do any clean up required due to any exceptions thrown -- then finally hand the return value over through the proxy to the caller.
Calling this.foo() directly, or passing 'this' to a caller so they can make direct calls as well, will skip all of that and the container will be effectively cut out of the picture. The 'getBusinessObject(Class)' method allows the bean instance to essentially get a proxy to itself so it can invoke its own methods and make use of the container management services associated with it -- interceptors, transaction management, security enforcement, etc.