This question already has answers here:
What is a callback method in Java? (Term seems to be used loosely)
(6 answers)
Closed 8 years ago.
I am reading the spring documentation. All the time I get this word "callback".
For example:
Lifecycle callbacks
Initialization callbacks etc.
How do we understand callback function ? And when you say "Lifecycle callbacks" in the spring, what does it mean ?
I have kept efforts in understanding this but I am not sure if I have understood correctly.
Please help.
LifeCycle
In the context of Spring beans (which I believe is the context of what you are reading - hard to tell with the little info you've provided), beans go through different lifecycle phases (like creation and destruction). Here are the lifecycle phases of the Spring bean you can hook into:
Callback
#R.T.'s wikipedia link to what a callback is, is a good starting point to understanding callbacks. In Java, the concept of callback is implemented differently.
In object-oriented programming languages without function-valued arguments, such as in Java before its 1.7 version, callbacks can be simulated by passing an instance of an abstract class or interface, of which the receiver will call one or more methods, while the calling end provides a concrete implementation.
A good example is given by #SotiriosDelamanolis in this answer, which I'll post here just for context.
/**
* #author #SotiriosDelamanolis
* see https://stackoverflow.com/a/19405498/2587435
*/
public class Test {
public static void main(String[] args) throws Exception {
new Test().doWork(new Callback() { // implementing class
#Override
public void call() {
System.out.println("callback called");
}
});
}
public void doWork(Callback callback) {
System.out.println("doing work");
callback.call();
}
public interface Callback {
void call();
}
}
LifeCycle Callback
By looking at the image above, you can see that Spring allows you to hook into the bean lifecyle with some interfaces and annotations. For example
Hooking into the bean creation part of the lifecycle, you can implements InitializingBean, which has a callback method afterPropertiesSet(). When you implements this interface, Spring pick up on it, and calls the afterPropertiesSet().
For example
public class SomeBean implements InitializingBean {
#Override
public void afterPropertiesSet() { // this is the callback method
// for the bean creation phase of the
// spring bean lifecycle
// do something after the properties are set during bean creation
}
}
Alternatively, you can use the #PostConstruct method for a non-InitializingBean implemented method, or using the init-method in xml config.
The diagram shows other lifecycle phases you can hook into and provide "callback" method for. The lifecycle phases are underlined at the top in the diagram
You can see more at Spring reference - Lifecycle Callbacks
The wiki has a good explanation:
In computer programming, a callback is a reference to executable code,
or a piece of executable code, that is passed as an argument to other
code. This allows a lower-level software layer to call a subroutine
(or function) defined in a higher-level layer.
Also check this interesting article Java Tip 10: Implement callback routines in Java
A sample example:
interface CallBack {
void methodToCallBack();
}
class CallBackImpl implements CallBack {
public void methodToCallBack() {
System.out.println("I've been called back");
}
}
class Caller {
public void register(CallBack callback) {
callback.methodToCallBack();
}
public static void main(String[] args) {
Caller caller = new Caller();
CallBack callBack = new CallBackImpl();
caller.register(callBack);
}
}
Paul Jakubik, Callback Implementations in C++.
Callbacks are most easily described in terms of the telephone system.
A function call is analogous to calling someone on a telephone, asking
her a question, getting an answer, and hanging up; adding a callback
changes the analogy so that after asking her a question, you also give
her your name and number so she can call you back with the answer.
Related
This question already has answers here:
Java listener must inherit from java.util.EventListener - why?
(2 answers)
Closed 2 years ago.
I can't find the answer to this question.
What is a java.util.EventListener? How does it work?
I have already done some research on google but I only found this, which isn't very clear: a tagging interface that all event listener interfaces must extend.
Can someone please help?
A listener is a class containing methods that are invoked when certain actions happen.
java.util.EventListener is a marker interface(an interface without any methods) that all listeners should implement.
In fact, it does not even add any functionality but it may be helpful with some IDEs and code-analysis tools.
So, if you want to create your own custom event (that you trigger), you need to somehow call all your listener methods when the event occurs.
For example, you can do this like the following:
At first, you create an interface for your listeners that extends EventListener:
public interface MyListener extends EventListener{
void onEvent();
}
Then, you will need to create a mechanism to register and call all the events:
private Collection<MyListener> listeners=new HashSet<>();
public void register(MyListener listener){
listeners.add(listener);
}
public void eventHappens(){
for(MyListener listener:listeners){
listener.onEvent();
}
}
Then, you can creator a Listener using
public class MyListenerImpl implements MyListener{
private String msg;
public MyListenerImpl(String data){
this.data=data;
}
#Override
public void onEvent(){
System.out.println(msg);
}
}
and you can register it using
register(new MyListenerImpl("Event occurs"));
Whenever a eventHappens() is called(you can call it if you e.g. receive a network packet), all your registered listeners will be executed.
For example:
register(new MyListenerImpl("listener 1 called"));
register(new MyListenerImpl("listener 2 called"));
System.out.println("calling event");
eventHappens();
would print
calling event
listener 1 called
listener 2 called
The first Google hit is the EventListener documentation, as you seem to have discovered.
See that blue navigation bar at the very top of the page? The fourth word is a “Use” link. Go to that.
EventListener provides typesafe polymorphism. For example, java.awt.Component has a getListeners method which requires a subclass of EventListener.
EventListener is actually part of the Java Beans specification. From section 6.4 of that specification:
Since the new Java event model is based on method invocation we need a way of defining and grouping event handling methods. We require that event handling methods be defined in EventListener interfaces that inherit from java.util.EventListener. By convention these EventListener interfaces are given names ending in “Listener”.
A class that wants to handle any of the set of events defined in a given EventListener interface should implement that interface.
I was looking at this project https://github.com/MSzturc/cdi-async-events-extension/,
which provides async events in CDI 1.X (built-in async came from 2.0).
Now I'm questioning this piece of code inside the custom Extension:
public <X> void processAnnotatedType(#Observes ProcessAnnotatedType<X> event, final BeanManager beanManager) {
final AnnotatedType<X> type = event.getAnnotatedType();
for (AnnotatedMethod<?> method : type.getMethods()) {
for (final AnnotatedParameter<?> param : method.getParameters()) {
if (param.isAnnotationPresent(Observes.class) && param.isAnnotationPresent(Async.class)) {
asyncObservers.add(ObserverMethodHolder.create(this.pool, beanManager, type, method, param));
}
}
}
}
public void afterBeanDiscovery(#Observes AfterBeanDiscovery event) {
for (ObserverMethod<?> om : this.asyncObservers) {
event.addObserverMethod(om);
}
}
Basically, while each Bean is being registered, it is looking at each method to see if a parameter has the #Async annotation.
Then, after the discovery step, it is registering the #Observes #Async methods.
Looking inside the addObserverMethod() method, provided by JBoss Weld 2, I see:
additionalObservers.add(observerMethod);
My question then is, wouldn't those methods be called twice? I mean, they may be registered twice, first by the container itself, then by calling the addObserverMethod() method.
I am not familiar with project, but from the first look it seems pretty outdated and not maintained.
As for the extension - it basically adds the "same" observer method (OM) again, with it's own OM implementation. So I would say the behaviour depends on CDI implementation as the spec does not guarantee what happens when you register "the same" OM again - is it replaced or is it just added like you say?
And by "the same" I mean the exact same underlying Java method although wrapped in a fancier coat.
Ultimately, you can easily try it and see for yourself, but I would advise against using that project as any problems you bump into are unlikely to be resolved on the project side.
I have a huge Part source code I have to touch at 1 place. It is violating a lot of principles so I would like to extract at least the function I had to modify which is a #UIEventTopic handler. There are no tests and I would like to add them here so I know I do not break existing functionality.
I would like to move away from this:
public class MyPart {
...
#Inject
#Optional
public void event(#UIEventTopic(EVENT) EventParam p) {
...
}
}
To something like this:
public class MyPart {
...
}
public class MyEventHandler {
#Inject
#Optional
public void event(#UIEventTopic(EVENT) EventParam p, MyPart part) {
...
}
}
With the Eclipse DI I see no easy way of creating an instance of the handler class. It cannot be a #Singleton because it is a Part which can have multiple instances, and adding the handler to the IEclipseContext in the #PostConstruct is ugly because it adds a circular dependency between the part and the handler. Is there a magic how I can enforce the instantiation through the e4xmi files, or some alternative way?
My current solution is to extract purely the functionality to a utility bean and return the data and set it on the part, but this is also something not too nice (requires a lot of additional null-checks, ifs, etc.).
I am not entirely sure that I understand your question, however, this is how I would proceed:
Extract Delegate
Move the code in event() to the MyEventHandler so that MyClass fully delegates the event handling
public class MyPart {
#Inject
#Optional
public void event( #UIEventTopic(EVENT) EventParam param ) {
new MyEventHandler().handleEvent( this, param );
}
}
class MyEventHandler {
void handleEvent(MyPart part, EventParam param) {
// all code from event() goes here
}
}
This should be a safe-enough refactoring to do without having tests - and in the end, you don't have a choice as there are no tests.
Ensure the Status Quo
Now I would write tests for handleEvent(), mocking the required methods of MyPart and thus make sure that I won't break existing behavior.
Implement new Feature
After that I would be able to make the desired changes to MyEventHandler::handleEvent in a test driven manner.
Clean Up
Then I would extract an interface from MyPart that has only those methods required for MyEventHandler to do its work. If said interface gets too big, it would indicate that there is more refactoring left to do.
I have this code that initializes Calligraphy default configuration.
public class MyApplication extends Application {
#Override
public void onCreate() {
super.onCreate();
// The initialization I want to move
CalligraphyConfig.initDefault(new CalligraphyConfig.Builder()
.setDefaultFontPath("fonts/MyFont.ttf")
.build()
);
}
}
I want to use Dagger 2 in my project but I don't fully understand what classes should I create and where to move this code in order to keep the project clean ?
In short, you probably wouldn't move anything. The problem with this library is that it uses static methods for initialization and utilization. Static methods are a pain when trying to do dependency injection.
The Library (or why you would not change anything)
It looks like this library is 'just' about switching the used fonts by wrapping the context. As such it does not really provide business logic to your project, but just adds to your views / UI.
Injecting a dependency rather than just calling static methods is most useful if you either want to be able to unit test (inject mocks) or easily swap modules / behavior. In the case of globally changing fonts, both seems less likely.
If on the other hand you really need (or want to) be able to test it, or just have a clean design...
...wrap it
Static methods are a pain, because you can not have objects holding the logic. Unless you wrap them. To properly do DI with static methods, you would have to define your own interface.
public interface CalligraphyManager {
/**
* Called on app start up to initialize
*/
void init();
// other methods, like wrapping context for activity
Context wrap(Context context);
}
You now have some manager to access the static methods. The implementation should be fairly simple, since you want to do proper DI the application context and path needed for init() would be passed into the constructor of your implementation. The creation of your manager can thus be handled by your ApplicationModule—just add some provides method
#Singleton
#Provides
// You would also have to provide the path from somewhere or hardcode it
// left as an exercise for the reader
CalligraphyManager provideCalligraphyManager(Context context, String path) {
return new ActualCalligraphyManager(context, path);
}
Your application would then look something like this:
public class MyApplication extends Application {
#Inject
CalligraphyManager mCalligraphy;
#Override
public void onCreate() {
super.onCreate();
mComponent = DaggerAppComponent.builder()
.appModule(new AppModule(this))
.build();
mComponent.inject(this);
// call the initialization
mCalligraphy.init();
}
}
Everything else is as usual. You have a singleton object in your application components graph, you can thus inject the same object into your activities and call `wrap´ where appropriate.
What about testing / mocking?
Since the whole reason of doing this is to make it 'testable', you can now easily provide a mock / stub object.
Create another implementation of the manager where init() would just do nothing, and wrap(Context) would just return the same context—a simple stub object.
I am somewhat new to the OSGi world. And some concepts still elude me.
I'm trying to create a graphical OSGi application using Swing, Equinox and Declarative Services. The goal is to ease the creation of plugins and extensions for the application.
I have stumbled with a design problem and, since I am doing this from the ground up, I want to use all the best practices I can.
I do have a bundle that contains the API and only exposes interfaces to be implemented as services.
public class SomeClass {
}
public interface Manager<T> {
void add(T obj);
void update(T obj);
void remove(T obj);
}
public interface SomeClassManager extends Manager<SomeClass> {
}
public interface Listener<T> {
void added(T obj);
void updated(T obj);
void removed(T obj);
}
public interface SomeClassListener extends Listener<SomeClass> {
}
Let's say I have a bundle (Core) that provides a service that is a manager of certain types of objects (It basically contains an internal List and adds, removes and updates it).
public class SomeClassCoreManager implements SomeClassManager {
private ArrayList<SomeClass> list = new ArrayList<SomeClass>();
private ArrayList<SomeListener> listeners = new ArrayList<SomeListener>();
protected void bindListener(SomeListener listener) {
listeners.add(listener);
}
protected void undindListener(SomeListener listener) {
listeners.remove(listener);
}
public void add(SomeClass obj) {
// Adds the object to the list
// Fires all the listeners with "added(obj)"
}
public void update(SomeClass obj) {
// Updates the object in the list.
// Fires all the listeners with "updated(obj)"
}
public void remove(SomeClass obj) {
// Removes the object from the list.
// Fires all the listeners with "removed(obj)"
}
}
I also have a second bundle (UI) that takes care of the main UI. It should not "care" for the object managing itself, but should be notified when an object is added, removed or changed in order to update a JTree. For that purpose I used a Whiteboard pattern: The UI bundle implements a service that is used by the Core bundle to fire object change events.
public class MainWindow extends JFrame {
private JTree tree = new JTree();
private SomeClassManager manager;
protected void activate() {
// Adds the tree and sets its model and creates the rest of the UI.
}
protected void bindManager(SomeClassManager manager) {
this.manager = manager;
}
protected unbindManager(SomeClassManager manager) {
this.manager = null;
}
}
public class SomeClassUIListener implements SomeClassListener {
public void added(SomeClass obj) {
// Should add the object to the JTree.
}
public void updated(SomeClass obj) {
// Should update the existing object in the JTree.
}
public void removed(SomeClass obj) {
// Should remove the existing object from the JTree.
}
}
My problem here is the following:
The MainWindow is a DS component. I am using its activator to initiate the whole UI. The instance creation is handled by OSGi.
In order to get the updates from the manager, I am exposing the SomeClassUIListener as a Declarative Service. Its instance is also handled by OSGi.
How should I access the instance of the JTree model from the SomeClassUIListener?
I have come up with several options but I am not sure which to use:
Option 1:
Use some kind of internal DI system for the UI bundle (like Guice or Pico) and put it in a class with a static method to get it and use it all over the bundle.
This approach seems to be frowned upon by some.
Option 2:
Inject a reference to the MainWindow (by turning it into a service) in the SomeClassUIListener through OSGi and go from there. Is this possible or advisable? Seems to me that it is the simpler solution. But, on the other hand, wouldn't this clutter the bundle with component config files as the UI got more and more complex?
Option 3:
Create a separate bundle only for listeners and use OSGi to update the MainWindow. This seems to me a bit extreme, as I would have to create an enormous amount of bundles as the UI complexity grows.
Option 4:
Use the MainWindow class to implement the Listener. But, the more services in the main UI bundle, the bigger the MainWindow class would be. I think this would not be a good option.
I cannot think of more options. Is any of the above the way to go? Or is there another option?
Thank you in advance.
Edit:
Just to clarify as Peter Kriens had some doubts about this question.
My goal here is to decouple the user interface from the Manager. By Manager I mean a kind of repository in which I store a certain type of objects (For instance, if you consider the Oracle's JTree tutorial at http://docs.oracle.com/javase/tutorial/uiswing/components/tree.html, the manager would contain instances of Books).
The Manager may be used by any other bundle but, according to my current plan, it would notify any listener registered in it. The listener may be the main UI bundle but may also be any other bundle that chooses to listen for updates.
I am not sure I completely grasp your proposal, and it feels like you are on your way to create a whole load of infrastructure. In OSGi this is generally not necessary, so why not start small and simple.
Your basic model is a manager and an extension. This is the domain model and I would try to flow things around here:
#Component(immediate)
public class ManagerImpl { // No API == immediate
List<Extension> extensions = new CopyOnWriteArrayList<Extension>();
JFrame frame = new JFrame();
#Reference(cardinality=MULTIPLE)
void addExtension( Extension e ) {
addComponent(frame, e.getName(), e.getComponent());
extensions.add(e);
}
void removeExtension( Extension e) {
if ( extensions.remove(e) ) {
removeComponent(frame, e.getName());
}
}
#Component
public class MyFirstExtension implements Extension {
public String getName() { return "My First Extension";}
public Component getComponent() { return new MyFirstExtensionComponent(this); }
}
Isn't this what you're looking for? Be very careful not to create all kinds of listeners, in general you find the events already in the OSGi registry.
Some option here would be to pass the tree model instance as the argument in the listeners methods.
public void added(JTree tree, SomeClass obj)
This way listeners manager would be responsible only for listeners logic, not for the tree state.
Another nice option would be to create a separated TreeProviderService, responsible for holding and serving singleton JTree instance for the application. In such case you would consume TreeProviderService directly from the listeners.
I propose to simply also use DS for the UI creation and wiring. If you use the annotations Peter mentioned you will not clutter your bundles with component descriptors in XML form.
So your listener is a #Component and you inject the UI elements it needs to update into it.
Btw. what you plan to do sounds a bit like databinding to me so you should also investigate what these offer already.
See: Swing data binding frameworks
Btw. you may also want to look for more advanced frameworks than swing. For example some time ago I did a small tutorial for vaadin: https://github.com/cschneider/Karaf-Tutorial/tree/master/vaadin
It already has a databinding for java beans. So this made it really easy for me to code the UI. The full UI is just this little class: https://github.com/cschneider/Karaf-Tutorial/blob/master/vaadin/tasklist-ui-vaadin/src/main/java/net/lr/tutorial/karaf/vaadin/ExampleApplication.java
In the old version I still needed a bridge to run vaadin in OSGi but version 7 should be quite OSGi ready.