I have two projects, A and B. B consumes A as a jar. B is not always used in other projects (for example, projects C, D, E, etc. can either consume or not consume B, but always consume A). I can modify both projects.
There is a controller in A that I want to add functionalities related to B's bussiness model (entities, services, that kind of stuff). Of course, writing the new functionality in A won't work (compiling mainly, but also would break the well-defined structure of both projects).
The controller in A is defined as a spring bean in the Java class itself, and also is related to a zul page that uses it. Relevant code:
Java
#Controller("userController")
#Scope("prototype")
public class UserController extends GenericForwardComposer
ZUL page
<window apply="${userController}" >
How could I add the functionality in B and avoid as much possible unnecesary complexity? I want to avoid extending the controller and adding a #Primary definition. Since I'm working with Java 8, I was thinking on interfaces with default behaviour, but I haven't figured how to make the execution pick an interface in B rather than in A. Composition is also an option, but the bean in A wouldn't be properly initializated (there are components in the zul page).
Any help or pointers will be appreciated.
From a ZK's perspective there's nothing to do here. So no need to look in this direction. (based on the details/code provided so far - unless your last comment ...
there are components in the zul page
... means/should indicate something specific)
It rather seems to be a Spring topic, how to resolve duplicate bean definitions (default in A, something advanced in B), if you don't like #Primary then maybe #Priority/#Order can help to determine which bean get's injected.
Another way to manage such scenarios are spring profiles or more general the #Conditional annotations which allow dynamic configuration/instantiation of beans.
E.g. spring-boot auto-configuration as these #ConditionalOn...-annotations, which I used in zk-springboot-autoconfig de-/activate beans based on the existence of certain classes on the classpath, or other conditions based on properties.
There are many ways to achieve a dynamic bean configuration in spring. In case you need dedicated help with ZK you can try the zk forum or zk support (disclaimer: I work for ZK)
Related
I just started getting into DI(dependency injection) frameworks and I was wondering should I inject every and any class or specific classes? How would I know which classes you should inject and which you shouldn't?
A lot of the tutorials(Dagger 2, Hilt, etc) that I've found don't seem to talk about this or don't explain it very well.
I don't have any code examples cause I'm trying out things as I read along with tutorials. Just trying to get a feeling of things.
Explain it as if I was 4 year old :)
My answer is no, you do not have to do that use dependency injection every time you need to create an object.
This is the intent of dependency injection according to Wikipedia
The intent behind dependency injection is to achieve separation of concerns of construction and use of objects. This can increase readability and code reuse.
So you should use dependency injection it would improve your code reuse and readability.
This article mentions some cases where you should use dependency injection to create objects
You need to inject configuration data into one or more components.
You need to inject the same dependency into multiple components.
You need to inject different implementations of the same dependency.
You need to inject the same implementation in different configurations.
You need some of the services provided by the container.
Imagine that you have username and password fields in an app that you would use to capture a user's detail, you do not have to use dependency injection to create a User object from the details, you can just create it directly, its not something that would be reused across your application, there are other object creation patterns that you should look into like factory pattern, abstract factory pattern, builder pattern e.t.c.
There's a certain number of classes which I always inject and never ask myself the question: the application context, shared preferences, DAOs, Retrofit, Json object. As you can see, these are usually related the third-party libraries or the Android framework.
Then there are classes which depend on those: the repository is a common example, but there are many more. For example you could have a preference manager which depends on shared preferences and context. Or you could have a class JsonExporter used to export user data which depends on DAOs and the Json mapper.
In turn, there are other classes which depend on those new classes: a view model/presenter in MVVM/MVP architecture could depend on both the repository and JsonExporter for example. At this point you have two choices:
Instantiate the class yourself. But that means you need to have access to all of the class' dependencies, which are only available through dependency injection...
so you might as well inject it. The cost of injection at this point is often very low, just adding #Inject to the constructor. Only the base dependencies have to be provided in a module.
From a certain number of injected base classes, the decision to inject those more nested in the dependency graph really comes automatically.
There are also cases where you'll have a class that depends on nothing. Perhaps you decided to extract code from a big class into another one. Or perhaps the class just has no dependencies. I probably wouldn't inject such a class, there's no point.
Singletons are often handy to inject because the dependency injection framework (e.g. Dagger) can make sure there's always only one instance automatically.
One reason why we do dependency injection is so that classes depend on abstractions, not concretions (aka inversion of control). It's useful to have your class depend on a Repository interface, because you can decide to provide it with the implementation you want, for example RealRepository in the app, and MockRepository in tests. Another example is flavors or build variants: an injected FlavorBehavior interface could have different implementations in two different flavors. It's not the class' responsability to decide which to use.
Note that this is not a definitive answer, and I'm not an expert on the subject. It's an opinion-based subject too.
If I have a set of useful reusable Spring components how can I make them available as a library such that other projects can use just whatever subset of those components are useful to them?
E.g. I have 4 classes, X1, X2, X3 and X4, each annotated with #Component (or #Service, #Controller or whatever) and I want to bundle them into a library.
Then I have project A that's only interested in using X1 and X3 and another project B that's only interested in using X3 and X4.
How do projects A and B selectively enable just the components that they are interested in?
I'm using Spring Boot so I guess I could annotate each of my components with #ConditionalOnProperty, e.g. I could annotate X1 etc. like so:
#ConditionalOnProperty("x1.enabled")
#Component
public class X1 {
Then downstream projects would have to add x1.enabled = true to their application.properties file if they wanted to use X1.
Is this the way to do things or is there some other standard approach for bundling components for reuse?
I can think of other approaches, e.g.:
Put each component in its own package and then downstream projects could use #ComponentScan to scan just the packages of the components they wanted to use.
I could leave off #Component on the component classes and mark them abstract and then leave it to any downstream project to simply subclass the components they want and add #Component to the subclass.
The first of those ideas sounds like a complete hack, the second doesn't sound so bad but one has to create subclasses simply in order to enable something (but at least it's fairly explicit what you're doing).
Just to note - I'm using an all annotation based configuration with no XML.
The first option that you proposed, to me is a good option. You can put your classes in different packages and the scan the packages that you're interested in.
But you don't like the first option, so I suggest you the following.
You can take off the #component, of your classes and defined as beans in the configuration (xml files or #configuration classes). At the end each project configure the classes that it needs.
You then can inject those beans into others beans of the every project.
To clear up a little confusion upon reading this question:
Using #Bean before a method/parameter name (in your #Configuration) will create a bean named the same as that method/parameter (by default). A function named myThing() will create a bean called "myThing"
Using #Component before a class name will create a bean with the same name except the first letter is lowercase. A class named MyThing will create a bean called "myThing"
You can indeed use #ComponentScan to scan for every #Component below the provided package name.
If you don't like that, you can create methods or parameters in your #Configuration that create instances of each of #Component you want to use.
If the creation of your beans is complicated, you can use #Import to import the whole #Configuration from your library.
I have been using Xml configuration for Spring Batch for a while, and feel it is simpler and concise. However, nowadays, people are suggesting to use javaconfig over xml. I googled this topic.
This site tells us why javaconfig is better https://blog.codecentric.de/en/2013/06/spring-batch-2-2-javaconfig-part-1-a-comparison-to-xml/
Top reasons to choose javaconfig over xml:
We want to do some basic configurations in the framework. People add
a dependency to our framework library and import those
configurations according to their needs. If these configurations
were written in XML, they would have a hard time opening them to
look what they are doing. No problem in Java.
There’s no navigability in XML. That may be okay as long as you
don’t have too many XML files and all of them are in your workspace,
because then you can take advantage of the Spring IDE support. But a
framework library usually should not be added as a project to the
workspace. When using Java based configuration you can perfectly
jump into framework configuration classes. I will talk more about
this subject in a following blog post.
In a framework you often have requirements
the user of the library has to fulfill in order to make everything
work, for example the need for a DataSource, a
PlatformTransactionManager and a thread pool. The implementation
doesn’t matter from the perspective of the framework, they just need
to be there. In XML you have to write some documentation for the
users of framework, telling them they need to add this and this and
this Spring bean under this name to the ApplicationContext. In Java
you just write an interface describing that contract, and people
using the library implement that interface and add it as a
configuration class to the ApplicationContext. That’s what I did
with the interface.
This site tells us why xml is better https://dzone.com/articles/consider-replacing-spring-xml
Top reasons to choose xml over javaconfig
Configuration is centralized, it’s not scattered among all different components so you can have a nice overview of beans and their wirings in a single place.
If you need to split your files, no problem, Spring let you do that. It then reassembles them at runtime through internal tags or external context files aggregation.
Only XML configuration allows for explicit wiring – as opposed to autowiring. Sometimes, the latter is a bit too magical for my own taste. Its apparent simplicity hides real complexity: not only do we need to switch between by-type and by-name autowiring, but more importantly, the strategy for choosing the relevant bean among all eligible ones escapes but the more seasoned Spring developers. Profiles seem to make this easier, but is relatively new and is known to few.
Last but not least, XML is completely orthogonal to the Java file: there’s no coupling between the 2 so that the class can be used in more than one context with different configurations.
I concluded that xmls can still be used, if you are creating standalone batch jobs and if you are not creating any new frameworks by integrating with Spring Batch.
Any disadvantage of xmls that I am missing out ?
Let me add a couple of additional thoughts on the topic.
What I really like when using javaconfig is the ability to create your jobs dynamically. E.g., you could have an inputparameter with filenames and then create a job that executes reading and processing this files in parallel by creating a step for every received filename. (using a MultiResourceItemReader would do this sequentially). Moreover, depending on inputparameter, you could also define the job flow differently.
My thoughts on your reasons why choosing xml over javaconfig:
point 1: this doesn't really count in my opinion. You can have your own configuration classes, you can define your own packages. You could even put them in own modules. This is just a matter, how you organize your code.
point 2: again, this doesn't count as well. You can split your configuration in as many classes as you'd like. You can use the #Import and #ContextScan annotation in order to integrate what you want into your context.
point 3: autowiring can also be very explicitly, if you do it by class and not by interface. Moreover, you can also call directly the method annotated with #Bean. An example:
#Configuration
public MyBeanFactory {
#Bean
public MyBeanInterface bean1() {
return ...;
}
#Bean
public MyBeanInterface bean2() {
return ...;
}
}
#Component
public MyBeanuser {
#Autowired
private MyBeanFactory beanFactory;
#PostConstruct
public void afterPropertiesSet() {
// this will actually set the bean that was created an registered in the
// spring context and not simply call the the method and create a new
// instance. So this wiring is very explicitly
setProperty1(beanFactory.bean1());
setProperty2(beanFactory.bean2());
}
In the end, I guess it is also a matter of taste. I was using xml-configuration for over 5 years in the context of spring batch. Two years ago, we completely switched to use javaconfig instead of xml. And honestly, I haven't found one single reason why I should want to go back to use xml. However, this is my "matter of taste".
So, yeah. That. I'm going through the tutorial one step at a time, so if the answer comes up later, forgive me. It's step 1 in this section.
I understand the ease of using this to have access in other methods in the EntryPoint class, but coming from the Spring MVC world, this sort of thing might be thought of as a controller and be a singleton (bean). Is it wrong to think this way in the GWT world?
With GWT you are coding as if it was a desktop AWT program. So, you do not have CDI or anything similar.
So, if you put all your information in a bean, you still would have to either:
keep a bean attribute in the class
pass it as a parameter in the method call
to get a reference to it (instead of retrieving it from CDI when needed)
While you can still use a bean when needed, these attributes are closely linked to the main class (in fact they are other graphical components to show). In general, I would only use bean when you have a bunch of attributes that are tightly coupled between them but are not tightly coupled to any other class.
Yes, I searched for questions about backing beans and I found many questions. I read them, and I get some parts of it but I need to ask another question, sorry.
After what I understand backing beans are needed because of JSF MVC pattern. Backing beans are the model. So if you have a page that displays a form, an image and a login box the backing beans will have getter/setter pairs for the data that needs to be exposed or changed in the view. And the backing beans will also have methods related to this such as what happen when you submit the form, login in etc.
So my question is if the statements above is correct, and the number of backing beans you make for the components above is dependent on how much code it is?
Would one backing bean exposing methods and getter/setter pairs for all components on this page be legal and "correct" (meaning that I don't do any wrong) in the same way as making 3 backing beans; one for each component would also be fine.
Does it all boil down to experience to see when you should separate vs. making one backing bean for each page, and also the logical part of it? I heard one guy made a backing bean for each component on the page but it sounds like you end up with a lot of small classes.
I would highly apprciate if somebody could verify and correct me.
It is legal for all components in a view to be bound to one managed bean for properties and actions. IDE tooling may encourage you to do this with a single backing bean.
From a class point of view however this approach lacks granularity and can make the managed beans difficult to test. If a class doesn't have a clearly defined purpose then it can be difficult to assert they are doing that job. See warning sign "Summing up what the class does includes the word “and”". All versions of JSF support dependency injection so it is relatively easy to rely on composition to assemble your managed beans.
This is a somewhat subjective topic and the answer depends on other factors (application scale; view design; page function.)