In my current application, I've run into this pattern in a couple of places: I have two service interfaces in a single bundle which do different but related jobs.
interface Service1 { ... }
interface Service2 { ... }
and want to have singleton components implementing both, but find each needs a reference to the other:
public class Service1Impl implements Service1 {
private Service2 service2;
...
}
public class Service2Impl implements Service2 {
private Service1 service1;
...
}
Which of the three OSGi component models (DS, Blueprint, and iPOJO) allow this: 1) when Service1Impl and Service2Impl are in the same bundle; 2) when they are in different bundles?
Declarative Services Specification, version 1.1:
112.3.5 Circular References
It is possible for a set of component descriptions to create a circular dependency. For example, if
component A references a service provided by component B and
component B references a service provided by component A then a
component configuration of one component cannot be satisfied without
accessing a partially activated component instance of the other
component. SCR must ensure that a component instance is never
accessible to another component instance or as a service until it has
been fully activated, that is it has returned from its activate method
if it has one.
Circular references must be detected by SCR when it
attempts to satisfy component configurations and SCR must fail to
satisfy the references involved in the cycle and log an error message
with the Log Service, if present. However, if one of the references in
the cycle has optional cardinality SCR must break the cycle. The
reference with the optional cardinality can be satisfied and bound to
zero target services. Therefore the cycle is broken and the other
references may be satisfied.
Blueprint specification explicitly allows this, provided at least one member of the dependency cycle takes others as properties and not arguments (121.2.6 Cyclic Dependencies):
When a member of a cycle is requested to provide a component instance,
the Blueprint Container must break the cycle by finding one breaking member in the cycle’s members. A breaking member must use property injection
for the dependency that causes the cycle. The Blueprint Container can pick
any suitable member of the cycle for breaking member, if no such member
can be found, then initialization fails or the getComponentInstance
method must throw a Component Definition Exception.
A breaking member must return a partially initialized component instance
when it is asked to provide an object. A partially initialized object has done
all possible initialization but has not yet been called with the initMethod (if
specified) nor has it been injected any of the properties that causes a cycle.
The finalization of the partially initialized component instance must be
delayed until the breaking member has been injected in all referring members of the cycles. Finalization means injecting any remaining unset properties and calling of the initMethod, if specified.
The consequence of partially initialized component instances is that they
can be used before they have all properties set, applications must be aware
of this.
All partially initialized component instances must be finalized before the
Blueprint Container enters the Runtime phase and before a call to the
getComponentInstance method returns a component instance. User code
that causes a dynamic cycle by recursively calling the
getComponentInstance method must be detected and cause a failure, these
cycles cannot be broken.
All detected cycles should be logged.
For iPOJO
Your specific situation is supported. I can't talk for other situations
without knowing further description though.
(answer received on the mailing list).
Strictly speaking, what you are saying is impossible, because of the circular dependency.
Service1 can only function once Service2 is active and vice versa, so there is no order in which a framework can start your services.
As far as I can see you can make it work if you make one of the service references optional, so it can supply its service before it has it's injected service, so the other serviceimpl can supply its service back.
You can do this in all three frameworks. iPojo has optional references, DS has a cardinality setting to service requirements (use 0..1 for an optional reference instead of 1..1). Blueprint I don't know that well, but I'm sure it can be done.
Regards, Frank
Related
In a Spring Boot Web Application layout, I have defined a Service Interface named ApplicationUserService. An implementation called ApplicationUserServiceImpl implements all the methods present in ApplicationUserService.
Now, I have a Controller called ApplicationUserController that calls all the methods of ApplicationUserServiceImpl under different #GetMapping annotations.
As suggested by my instructor, I have defined a Dependency Injection as follows:
public class ApplicationUserController {
private final ApplicationUserService applicationUserService; //This variable will work as an object now.
public ApplicationUserController(ApplicationUserService applicationUserService) {
this.applicationUserService = applicationUserService;
}
#GetMapping
//REST OF THE CODE
}
I am new to Spring Boot and I tried understanding Dependency Injection in plain English and I understood how it works. I understood that the basic idea is to separate the dependency from the usage. But I am totally confused about how this works in my case.
My Questions:
Here ApplicationUserService is an Interface and it's implementation has various methods defined. In the code above, applicationUserService now has access to every method from ApplicationUserServiceImpl. How did that happen?
I want to know how the Object creation works here.
Could you tell me the difference between not using DI and using DI in this case?
Answers
The interface layer is used for abstraction of the code it will be really helpfull when you want to provide different implementations for it. When you create a instance you are simply creating a ApplicationUserServiceImpl and assigning it into a reference variable of ApplicationUserService this concept is called upcasting. Even though you have created the object of child class/implementation class you can only access the property or methods defined in parent class/interface class. Please refer this for more info
https://stackoverflow.com/questions/62599259/purpose-of-service-interface-class-in-spring-boot#:~:text=There%20are%20various%20reasons%20why,you%20can%20create%20test%20stubs.
in this example when a applicationusercontroller object is created. The spring engine(or ioc container) will create a object of ApplicationUserServiceImpl (since there is a single implementation of the interface ) and returns to controller object as a constructor orgument which you assign to the refrence variable also refer the concept called IOC(Invertion of control)
as explained in the previous answer the spring will take care of object creation (object lifecycle)rather than you explsitly doing it. it will make the objects loosely coupled. In this the controll of creating the instances is with spring .
The non DI way of doing this is
private ApplicationUserService applicationUserService = new ApplicationUserServiceImpl()
Hope I have answered your questions
this analogy may make you understand better consider an example, wherein you have the ability to cook. According to the IoC principle(principal which is the basis of DI), you can invert the control, so instead of you cooking food, you can just directly order from outside, wherein you receive food at your doorstep. Thus the process of food delivered to you at your doorstep is called the Inversion of Control.
You do not have to cook yourself, instead, you can order the food and let a delivery executive, deliver the food for you. In this way, you do not have to take care of the additional responsibilities and just focus on the main work.
Now, that you know the principle behind Dependency Injection, let me take you through the types of Dependency Injection
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.
In OSGi R6 I desire to programmatically validate user-supplied String configuration properties plus a service factory PID against what is supported by whatever configurable #Component (or ManagedServiceFactory) that declares it configures this PID, e.g. #Component(configurationPid=some.service.factory.pid, ...). Additionally, I want to somehow convert valid String properties to their appropriate property types. Looking through the OSGi Compendium, it seems the Metatype Service is what I'm looking for.
If that's correct, given the following:
Applicable components uses component property types to specify their configuration
Component property types are annotated with #ObjectClassDefinition
Components are annotated with #Designate, mapping it to the applicable #ObjectClassDefinition
Is this the most straightfoward way to map factory PIDs to their ObjectClassDefinition:
Call BundleContext.getBundles(). For each bundle, call MetaTypeService.getMetaTypeInformation(Bundle).
For each returned MetaTypeInformation call MetaTypeInformation.getFactoryPids() and filter on the factory PIDs I care about.
For applicable MetaTypeInformation, call MetaTypeInformation.getObjectClassDefinition(String, String) to obtain the ObjectClassDefinition, using either a default or specific locale.
(Tangential, the above seems expensive to perform each time, so caching bundle IDs, mapping them to associated factory PIDs, and keeping the cache up-to-date somehow seems appropriate.)
Or, is there some other OSGi magic that can be programmatically queried with a service factory PID, which returns something that gets to some ObjectClassDefinition quicker than the above process?
Update 1
Stepping back, I'm writing a CRUD-wrapper around ConfigurationAdmin for each of my configurable components. I'm trying to avoid createFoo, deleteFoo, updateFoo, createBar, ... My application happens to be amenable to URIs. So my working approach was to use Metatype Service, pass in a parsed URI query (Map<String, List<String>>), and then utilize Metatype Service to validate and reconstruct these values, circling back to the OP. (On the side, seems like a not-pretty hack to me.)
Another approach was to use aQute.bnd.annotations.metatype.Configurable.createConfigurable(Class, Map), which I preferred more! Until I saw this bnd GitHub comment:
The bnd metatype annotations are deprecated in bnd 3.2 and will be removed in bnd 4.0. These annotations are replaced by the OSGi metatype annotations.
So I didn't want to rely on that package if it's going away soon. I looked at what Felix does and didn't want to use their equivalent Configurable class. I'm all ears on different approaches!
Update 2
Reducing this more, I'd like to validate potentially user-supplied key/values configuration properties to ensure they're applicable for some configuration pid, prior to calling ConfigurationAdmin.createFactoryConfig. Maybe this is overkill?
I once created a class that takes the configuration class, creates a proxy, and then uses this proxy to get the name of the method and the type. It was used something like this:
ConfigHelper<Config> helper = new ConfigHelper( Config.class, "my.pid");
int port = helper.get().port(); // get the configuration
helper.set( helper.get().port(), 1000);
helper.update();
The proxy you get from the get would record the method when one of the methods is called. On the set method it would use the last called proxy method to identify the property. It would then convert the given value to the property type based on the method's return value. The bnd converter is ideal for this but I think Felix now has a standard OSGi converter. (Which is based on the ideas of the bnd converter.)
The method name is then used as the property. The name mangling necessary is defined in an OSGi spec. This allows you to use underscores, Java keywords, and dotted names.
So this would allow you to roundtrip configurations. No worry about the types, they will automatically fall in their place.
Updated This is updated after I understood the question better
Updated 2 Added an example at https://github.com/aQute-os/biz.aQute.osgi.util/tree/master/biz.aQute.osgi.configuration.util
I am reading the 《Spring in Action》, and it says "singleton beans in Spring often don't maintain state because they're usually shared among multiple threads", but in my opinion, a bean in Spring is a POJO, so how can it not maintain state?
I am reading the 《Spring in Action》, and it says "singleton beans in
Spring often don't maintain state because they're usually shared among
multiple threads", but in my opinion, a bean in Spring is a POJO, so
how can it not maintain state?
Yes, it's better for a Spring/Singleton to not have a state (of course it can uses other Spring/Singletons [also them without a state]) so you can call its methods from different threads without worring about they could messed up its state (it doesn't have one :-)).
Let's think about a calculator that stores its intermediate results inside an internal stack, what can happen if two threads try to calculate something at the same time?
A Spring/Singleton is annotated (and if it's not it's just like it would be) and lives inside the spring context , it's not a POJO.
If you want to have a Spring/Bean with a state you have to use the scope "prototype", with this kind of scope every time you get a bean you will get a difference instance.
Sorry for the bad english
The book is implying that the state of a bean may not be trustworthy at a given point in time due to manipulation of its state by another thread. If multiple threads are accessing the same instance of a bean you cannot be sure of what state changes have occurred on the bean prior to using it. Since Spring uses Singletons by default there is only one instance of a bean. If multiple threads hit the bean at the same time there could be issues with the state of the bean.
So your correct that the beans will maintain state, however the state may be unreliable due to modifications from other threads.
In a typical web application, you have multiple threads (one per request) and all the requests are using the same beans. In a typical layered application, they will uses a Controller which uses then a Service which uses then a Repository. All of these beans should be singletons without any state. Otherwise you will have bugs due to concurrency (e.g. one thread modifies data in a singleton while another thread do the same).
I think that your misunderstanding comes from saying that bean in Spring are POJO. Most of Spring beans are stateless beans which I would not describe as POJO.
A Spring bean is considered a POJO in the sense that it does not need to adhere to special requirements (implement certain interfaces, extend particular class, be specific in some way, etc.) to be used with Spring.
Depending on the requirements a Spring bean might need to maintain, and operate on, its state.
It also depends on the requirements to consider if the Spring bean should be a singleton or not.
If a singleton Spring bean is maintaining its own state, proper safeguards must be taken to ensure correct concurrent access/modification.
Confusion comes from a general pattern used in enterprise applications where Spring beans are used to implement bulk of the system logic, and support operations.
In these scenarios, generally its a good practice to not have any state in the Spring bean itself, and just be an extension of the Value Object/Data Transfer Object that contain actual state.
Since these Spring beans are not going to maintain their own state, they are almost always created as singletons.
SomeClass, SomeOtherClass and Situation are all POJO in below code.
SomeClass and SomeOtherClass are Spring beans but Situation is not, which is a DTO.
class SomeClass {
private int x; // not restricted
public void handleSituation(Situation s) {
// may or may not use/modify SomeClass state represented by 'x'
// one approach is to provide all required information through parameters
}
}
class SomeOtherClass {
#Autowired
private SomeClass sc;
public void process() {
// gets called from another object
Situation z = new Situation();
sc.handleSituation(z);
// other processing
}
}
<!-- default scope = singleton -->
<bean id="someClassBean" class="SomeClass"/>
<bean id="someOtherClassBean" class="SomeOtherClass">
<property name="someClass" ref="someClassBean"/>
</bean>
This is a slight variation from pure OOP in which above would be coded similar to following.
class SomeOtherClass {
public void process() {
// gets called from another object
Situation z = new Situation();
z.handle();
// other processing
}
}
I find myself struggling with the fuzz around the concept of string-based 'Service Locators'.
For starters, IoC is great, and programming to interfaces is the way to go. But I fail to see where the big benefit lies in the yellow-pages pattern used here, apart from compilation-less reconfigurability .
Application code will use a (Spring) container to retrieve objects from. Now that's nice: since the code needs to know only the needed interface (to cast to), the Spring container interface, and the name of the needed object, a lot of coupling is removed.
public void foo(){
((MyInterface) locator.get("the/object/I/need")).callMe();
}
Where, of course, the locator can be populated with a gazillion of objects of all kind of Object derivatives.
But I'm a bit puzzled by the fact that the 'flexibility' of retrieving an object by name actually hides the dependency in a type-unsafe, lookup-unsafe manner: where my compiler used to check the presence of a requested object member, and it's type, now all of that is postponed to the runtime phase.
The simplest, functionally allright, pattern I could think of is a giant, application wide struct like object:
public class YellowPages {
public MyInterface the_object_i_need;
public YourInterface the_object_you_need;
....
}
// context population (no xml... is that bad?)
YellowPages locator = new YellowPages();
locator.the_object_i_need=new MyImpl("xyx",true),
locator.the_object_you_need=new YourImpl(1,2,3)
public void foo(){
locator.the_object_i_need.callMe(); // type-safe, lookup-safe
}
Would there be a way/pattern/framework to ask the compiler to resolve the requested object, and check whether it's type is ok? Are there DI frameworks that also do that?
Many thanks
What you are describing is an anti-pattern, plain and simple. Dependency injection (done via the constructor if possible) is the preferred way to do Inversion of Control. Older articles on IOC talk about service location as a viable way to implement the pattern, but you'd be hard pressed to find anyone advocating this in more recent writings.
You hit the nail on the head with this statement:
But I'm a bit puzzled by the fact that the 'flexibility' of retrieving
an object by name actually hides the dependency in a type-unsafe,
lookup-unsafe manner:
Most modern DI frameworks can get around the type-unsafe part, but they do hide the dependency by making it implicit instead of explicit.
Good article on this topic:
Service Locator is an Anti-Pattern
Spring is the only DI framework that I've used, so I can't speak for others, but even though Spring give you the ability to request an object by its name in your code, you don't have to get your Spring beans by name -- in fact, if you do, you're not really capitalizing on the "I" (inversion) in IOC.
The whole principle behind Spring/DI is that your objects shouldn't be asking for a particular object -- it should just have whatever objects it needs handed to it by the IOC container. The distinction is subtle, but it's there. The former approach would resemble the code that you pasted:
public void foo(){
((MyInterface) locator.get("the/object/I/need")).callMe();
}
The latter approach, by contrast, doesn't depend on any service locator, nor does it depend on the "name" of the object that it wants:
private ObjectINeed objectINeed;
public void setObjectINeed(ObjectINeed objectINeed) {
this.objectINeed = objectINeed;
}
public void foo(){
objectINeed.callMe();
}
It's the IOC container that calls the setObjectINeed() method. DI is definitely tackles the same problem as the service locator pattern, but it goes that extra step towards getting rid of the dependency on your service locator class.