I like to add Spring to my Scala projects for educational purposes. But I do not understand the advantage of Spring Scala to decouple components.
I have created a simple configuration:
import org.springframework.scala.context.function.FunctionalConfiguration
class Configuration extends FunctionalConfiguration {
bean() {
new Service()
}
}
and a simple service:
class Service {
def method = "Bonjour tout le monde!"
}
and then an application which uses both:
import org.springframework.scala.context.function.FunctionalConfigApplicationContext
object Application extends App {
implicit val context = FunctionalConfigApplicationContext(classOf[Configuration])
val service = context.getBean(classOf[Service])
println(service.method)
}
This is just my interpretation and implementation of the Spring Scala examples.
My application still has knowledge of the Service class. I could just write:
val service = new Service() // instead of asking for a Bean which has classname Service
println(service.method)
with the same effect.
Am I missing something?
This does decouple your use of the Service from the instantiation of it. E.g. if in the future Service changes to depend on some other InnerService, or has some initialization that can't be done in the constructor for some reason but needs to happen in a method call before it's used (.connectToDatabase() or some such), or if you wanted to replace the Service with a mock one for testing, then you can do this without changing these two lines of code:
val service = context.getBean(classOf[Service])
println(service.method)
If you program to an interface rather than implementation, e.g.
trait IService {
def method: String
}
class Service extends IService...
val service = context.getBean(classOf[IService])
then you also make it easy to swap out the Service for a different implementation, though given the extra lines of code I probably wouldn't bother doing this until I actually had more than one implementation.
I'm not sure that Spring carries its own weight (it's a very large and complex library), particularly in Scala with its more concise constructor syntax. But whether you use Spring or not, it's worth separating the construction of your dependencies and "wiring up" of your application from their actual use. IMO a class Foo that uses Service should accept it, explicitly via its constructor, class Foo(service: Service), and leave the construction/initialization of Service to a class/or function dedicated to that.
Related
When spring was introduced its advice to use an interface between different layers like Controller,Service,DAO instead of directly calling them using actual class reference.
In new age of Spring 5.x and Spring Boot 2.x do we need to still use interface between Controller and Service class. In my case I am developing a REST application with single GET method which call DB and do some business logic. So In my service I have only one method in this case still I do need to use ServiceInterface to call my actual ServiceImpl? what is best practice and is there any specific advantage of using ServiceInterface in this scenario?
Below is Sample code without ServiceInterface
public class MyTestController{
private MyTestServiceImpl myTestServiceImpl;
public MyTestController(MyTestServiceImpl myTestServiceImpl){
this.myTestServiceImpl = myTestServiceImpl;
}
#GetMapping("/test")
public String getTestString(){
myTestServiceImpl.getTestString();
}
}
#Service
public class MyTestServiceImpl(){
private MyTestRepository myTestRepository;
//constructor
//Service method impl
}
In very small applications, it doesn't really matter, because it is still very easy to keep track of all the classes and what classes do what. In a large scale enterprise application it can quickly become a cluttered mess. For example, if you have a rest endpoint/controller that has 100 methods, and it in turn calls 50 methods in your DAO. If you at some point decide to change the DAO methods, you will now have to change all 100 methods in the controller/endpoint. Whereas if you have a service layer in between to bridge the DAO and rest controller you only have to change the service methods.
Another point as #p.streef has mentioned is the seperation of classes and their functions. You can have a modular application wherein the service layer handles all the business logic and rules, the DAO is only responsible for database operations and the controller's only job is to send and receive data. The S in S.O.L.I.D stands for Single responsibility principle, so instead of the service layer is supposed to handle only receiving and transmitting data, and not business logic.
However, if you are building a very very small application then it shouldn't matter.
I am wondering what is the current best practice as to the use of factory pattern within the context of Spring framework in using dependency injection. My wonder arises about whether the factory pattern is still relevant nowadays in light of the use of Spring dependency injection. I did some searching and see some past discussion (Dependency Injection vs Factory Pattern) but seem there is different view.
I see in some real life project in using a Map to hold all the beans and rely on autowiring to create those beans. When the bean is needed, it get it via the map using the key.
public abstract class Service {
//some methods
}
#Component
public class serviceA extends Service {
//implementation
}
#Component
public class serviceB extends Service {
//implementation
}
Map<String, Service> services;
But I see there is some difference among the two approaches.
Using the above method, all beans are created on application start up and the creation of object is handled by the framework. It also implies there is only one bean for each type.
While for factory pattern, the factory class creates the object on request. And it can create a new object for each request.
I think a deeper question may be, when Spring framework is used in a project, should it be strived to not create any object inside a class, which means the factory pattern ( or any creational design patterns?) should not be used, as Spring is supposed to be the central handler of the objects dependency ?
The answer to this question can be really deep and broad, I'll try to provide some points that hopefully will help.
First off, spring stores its beans (singletons) in the ApplicationContext. Essentially this is the map you're talking about. In a nutshell, it allows getting the bean by name, type, etc.
ApplicationContext, while being a really important concept, is not the whole Spring, in fact Spring framework allows much more flexibility:
You say, using a map implies that all the beans will be created at the beginning of the application and there is one instance of the bean.
Spring has a concept of Lazy beans, basically supporting a concept of beans being actually created only when they're required for the first time, so Spring supports the "delayed" beans initialization
Spring also allows more than one instance of a bean per type. So this map is more "advanced". For example you can create more than one implementation of the interface and use declare both as beans. As long as you provide enough information about what bean should be injected to the class that might use them (for example with a help of qualifiers suppored in spring), you're good to go. In addition, there are features in spring IoC container that allow injecting all registered implementations of an interface into a list:
interface Foo {}
#Component
class FooImpl1 implements Foo {}
#Component
class FooImpl2 implements Foo {}
class Client {
#Autowired
List<Foo> allFoos;
}
Now you say:
While for factory pattern, the factory class creates the object on request. And it can create a new object for each request.
Actually Spring can create objects per request. Not all beans have to be singletons, in general spring has a concept of scopes for this purposes.
For example, scope prototype means that Spring will create a bean upon each usage. In particular one interesting usage that spring supports in variety of ways is Injecting prototype bean into singleton. Some solutions use exactly like a factory (read about annotation #Lookup others rely on auto-generated proxy in runtime (like javax.inject.Provider). Prototype scope beans are not held in the application context, so here again spring goes beyond a simple map abstraction.
Last feature that you haven't mentioned is that sometimes even for singletons the initialization can be a little bit more complicated then calling a constructor with Parameters. Spring can address that by using Java Configurations:
#Configuration
public class MyConfig {
public SomeComplicatedObject foo(#Value("...") config, Bar bar) {
SomeComplicatedObject obj = new SomeComplicatedObject() // lets pretend this object is from some thirdparty, it only has no-op constructor, and you can't place spring annotations on it (basically you can't change it):
obj.setConfig(config);
obj.setBar(bar);
return obj;
}
}
The method foo here initializes the object SomeComplicatedObject and returns it. This can be used instead of factories to integrate "legacy" code (well, java configurations go way beyond this, but its out of scope for this question).
So bottom line, you Spring as an IoC container can provide many different ways to deal with object creation, in particular it can do everything that factory design pattern offers.
Now, I would like to also refer to your last sentense:
I think a deeper question may be, when Spring framework is used in a project, should it be strived to not create any object inside a class, which means the factory pattern ( or any creational design patterns?) should not be used, as Spring is supposed to be the central handler of the objects dependency ?
Indeed you don't have to use Factory Pattern when using Spring, since (as I hopefully have convinced you) provides everything that factory can do and more.
Also I agree that spring is supposed to be the central handler of the objects dependency (unless there are also parts of the application which are written in a different manner so you have to support both :) )
I don't think we should avoid using "new" altogether, not everything should/can be a bean, but I do see (from my subjective experience, so this is arguable) that you use it much less leaving the creation of most of the objects to Spring.
Should we avoid a usage of any creation design pattern? I don't think so, sometimes you can opt for implementing "builder" design pattern for example, its also a creational pattern but spring doesn't provide a similar abstraction.
I think if your project uses Spring framework you should use it. Although it depends on your project design e.g. You may use creational patterns along side with Spring IoC. e.g when you have abstraction layers not framework dependant (agnostic code)
interface ServiceFactory {
Service create(String type);
}
#Component
class SpringServiceFactory implements ServiceFactory {
#Autowired private ApplicationContext context;
Service create(String type) {
return context.getBean(type)
}
}
I use Factory pattern as well when I refactor legacy not unit testable code which also uses Spring Framework in order to implement unit tests.
// legacy service impossible to mock
class LegacyApiClient implements Closeable {...}
#Component
class LegacyApiClientFactory {
LegacyApiClient create(String endpoint) {
return new LegacyApiClient(endpoint);
}
}
#Component
class OtherService {
private final String endpoint
private final LegacyApiClientFactory factory;
OtherService(#Value("${post.endpoint}") String endpoint,
LegacyApiClientFactory factory) {...}
void doCall {
try (LegacyApiClient client = factory.create(endpoint)) {
client.postSomething();
}
}
}
....
// a random unit test
LegacyApiClient client = mock(LegacyApiClient.class)
LegacyApiClientFactory factory = mock(LegacyApiClientFactory.class)
OtherService service = new OtherService("http://scxsc", factory);
when(factory.create(any())).thenReturn(client)
service.doCall()
....
I want to initialize a model class that is a #SliceResource into an Osgi Service.
Is there a way to do this? Thanks!
In an AEM project that uses Slice, the idiomatic way to obtain a graph of objects in an OSGi service is by obtaining a reference to an Injector.
try (InjectorWithContext injector = InjectorUtil.getInjector(INJECTOR_NAME, resolver)) {
final ModelProvider modelProvider = injector.getInstance(ModelProvider.class);
MyModel myModel = modelProvider.get(MyModel.class, knownResource);
//do something with the model
}
Keep in mind that this can be used not just to instantiate a class annotated with #SliceResource but to build an arbitrary graph of objects using Guice as the Dependency Injection framework. It's a very powerful tool that allows you to manage all sorts of objects, possibly in different injection contexts (More information here)
Remember that the injector needs to be closed once you're done using it. Fortunately, the InjectorWithContext interface extends the AutoCloseable interface so you can use it in a try-with-resources block, as shown above.
Use InjectorUtil to obtain an injector. The INJECTOR_NAME can be found in your Activator where the Injector is instantiated and bindings between interfaces and implementations are registered.
ModelProvider#get allows you to inject a model in a context specified by the second argument. This can be a Resource instance or a path.
I've learned a lot recently about Spring and one thing i think i might be misunderstanding is the #Autowired annotation, especially when using it in constructors. You see, the app i'm developing is a service so basically EVERYTHING is initialized within a constructor. The only actual user-driven events that happen are buttons that restart certain modules of the service. This is my main method :
ConfigurableApplicationContext ctx = new SpringApplicationBuilder(MDHIS_Service.class)
.headless(false).web(false).run(args);
java.awt.EventQueue.invokeLater(() ->
{
MDHIS_Service frame = ctx.getBean(MDHIS_Service.class);
frame.setSize(1024, 768);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
This is the constructor of my main class, where basically everything happens. I have omitted the calls to the methods initializing each module to shorten it :
#Autowired
public MDHIS_Service(GlobalParamService globalParamService, LogEntryService logentryService, InterfaceService interfaceService,
ConnectionService connectionService, OutboundMessageService outboundMessageService, OutboundMessageHistoryService outboundMessageHistoryService,
InboundMessageService inboundMessageService, FacilityService facilityService, ModuleStatusService moduleStatusService,
SequenceService sequenceService)
{
this.globalParamService = globalParamService;
this.logEntryService = logentryService;
this.interfaceService = interfaceService;
this.connectionService = connectionService;
this.outboundMessageService = outboundMessageService;
this.outboundMessageHistoryService = outboundMessageHistoryService;
this.inboundMessageService = inboundMessageService;
this.facilityService = facilityService;
this.moduleStatusService = moduleStatusService;
this.sequenceService = sequenceService;
}
My main class has a private final global variable for each service. Each module is a separate thread and i'm finding myself having to pass those variables to the constructor of each module which in term stores them into it own private final variables. The way i'm doing things right now #Autowired is pretty much useless since i'm having to pass the instance around. Is there a way to better use #Autowired? This service is used as the backend for a large web app and i find myself making much better use of the annotation in there. I did a lot of research on this topic and i did try the #PostContruct annotation but all i ever got was null services.
Any help would be appreciated.
Thanks!
I figured out my problem, and it was a pretty dumb one. First off, i had not annotated my main class with #Component so Spring never bothered to inject the dependencies in it. Secondly, I did not realize that a method annotated with #PostContruct would run by itself after the constructor runs WITHOUT NEEDING TO EXPLICITELY BE CALLED!
I moved all my initialization code to an init method annotated with #PostConstruct and annotated my main class with #Component, everything is working now!
You typicall don't have to use a constructor + #Autorwired, you can directly use autowired on fields and spring would fill the dependencies for you:
#Component
public class MDHIS_Service {
#Autowired
private GlobalParamService globalParamService;
}
What is important to understand is that for spring to work, you must let it create the objects for you, and not calling the constructors explicitely. It would then fill the dependencies as needed. This is done by declaring the service as a component (for example with the #Component annotation) and never create the service yourself but getting them from dependency injection.
The first object you start with has to have been created by spring and returned by the application context.
What you gain in exchange is that you don't have to forwared everything explicitely. A sub-sub-sub service quite distant from the root of the application can depend on anything it has visibility without you having to forward the reference all the way.
I would advise to take a look a the spring reference documentation, it quite detailled and complete:
https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#spring-core
Edit: I'll try to clarify a bit with an example... What do the init code of the various service actually does ?
Maybe it set the dependencies. Then just autowire them:
#Component
MySubService {
#Autowired MySubSubService mySubSubService;
}
Maybe it does some more thing than setting fields so you can add on top an init method that do it and this init method can eventually call the other services.
#Component
MySubService {
#Autowired MySubSubService mySubSubService;
#PostConstruct
public void init() {
//Init code that may use mySubSubService.
}
}
You don't have to declare a constructor and forward dependencies yourself, sprint does it for you.
The only case where you'd have problem is if finally you need some parameters that are not dependency to the init method. But even in that case you could do it from you main code. That's actually what you did with the main service calling the various setters rather than messing with the constructor to set theses values.
The short question:
Does Castle Windsor have something similar to Spring.Net's "Lookup Method Injection" that can be configured from XML, which provides the ability to fetch transient instances from the container without the class being aware of the IoC container?
The long question:
I'm a long time Spring/Spring.Net user and I have been experimenting with Castle Windsor, by trying to port a project over to it. Spring.Net has a concept of "Lookup Method Injection" which (from the Spring docs)...
Lookup method injection is the ability of the container to override methods on container managed objects, to return the result of looking up another named object in the container. The lookup typically involves a prototype object as in the scenario described in the preceding section. The Spring framework implements this method injection by a dynamically generating a subclass overriding the method using the classes in the System.Reflection.Emit namespace.
What this means is, If I had the following...
public class SomeTransient
{
// ... I have dependencies that need to be filled by IoC container
}
public class SomeClass
{
public virtual void Work()
{
var o = CreateTransient();
}
public virtual SomeTransient CreateTransient() { }
}
I can instruct Spring to override the CreateTransient method, and have that method return a new container created transient instance (with it's dependencies initialized) each time the method is called.
The unique part of this is, it doesn't require direct links to the Spring Framework (eg. SomeClass doesn't have to implement a specific interface).
Is there something similar in Castle Windsor to accomplish this via XML?
(I will eventually move away from XML config, but at the moment I'm just trying to get it running)
Castle has something better; Typed Factories.
You can also inject even a delegate!
http://stw.castleproject.org/Windsor.Typed-Factory-Facility-delegate-based-factories.ashx
It is better because it does not depend on dynamically generation code, and it looks much more cleaner.
It looks much more cleaner because the class doesn't depend on someone overriding that method. It is impossible to test this class without subclassing.
If you really want to do something like this, i would expect:
public abstract class SomeClass
{
public abstract SomeTransient CreateTransient();
}
but... again it doesn't feel right.
Edit 2
Unity 2 support these kind of delegate factories; you can read more here:
http://www.truewill.net/myblog/index.php/2010/05/06/unity_2_0_combining_injectionfactory_and
thanks to #eiximenis