I have a question about heritage and CDI.
Given two interfaces:
Car interface
SportCar that extends Car
interface Car {
}
interface SportCar extends Car{
}
class DefaultCar implements Car {
}
#FerrariQualifier
class DefaultSportCar implements SportCar {
}
What I would like to inject:
#Inject
private Car car; //inject DefaultCar
#Inject
#FerrariQualifier
private Car ferrari; //inject DefaultSportCar
#Inject
private SportCar sportCar;//inject DefaultSportCar
How can I do that?
Without any further examples or explanation, you'd need to inject the first one with qualifier #Default.
This obviously requires any further 'Car' to have a non-#Default qualifier attached to it, otherwise you have an ambiguous resolution and you're trying to shoehorn something into CDI that doesn't fit.
I think you misunderstood the CDI injection a bit. Especially that you want to do this:
#Inject
private Car car; //inject DefaultCar
Because any car implementation (sport car or ordinary one) will fit here and you will end up with ambiguous resolution.
As a temporary solution, you might make use of the #Default qualifier as noted by user covener but this is bound to break as soon as you introduce any other car implementation without qualifier.
The cleanest solution is perhaps re-thinking the design and altering the hierarchy like this:
interface Car {
// all cars, place common methods here
}
interface SportCar extends Car{
// interface for all sport cars
}
interface ClassicCar extends Car{
// interface for all non-sport cars
// this is what you will inject
}
class DefaultCar implements ClassicCar {
}
#FerrariQualifier
class DefaultSportCar implements SportCar {
}
With this you can then:
#Inject
private ClassicCar car;
And get an instance of DefaultCar. Rest of your injections will work the same way.
The other solution is to use qualifiers.
Generally speaking - whenever you bump into ambiguous resolution, you have more than one bean eligible for injection and you need to narrow the selection by either using qualifiers or injecting a more specific interface/class.
Related
I have a Repository interface that has two implementations. One reads data from a locally stored CSV file while the other reads from an Amazon Dynamo DB. I would like to be able to switch between which implementation I'm using based on an application property or custom build profile. I would normally use a Factory to retrieve the correct class at runtime, but I would like to do this with injection if possible.
I found a similar question using Spring boot but couldn't find an equivalent that would work in Quarkus Spring choose bean implementation at runtime
I also tried implementing a Configuration class similar to what is found in the docs here but again didn't have much luck. https://quarkus.io/guides/cdi-reference#default_beans
It feels like I'm missing something obvious so any pointers would be much appreciated.
Here is a simple example of my classes:
#ApplicationScoped
public class ExampleService {
#Inject
ExampleRepository repository;
public List<Data> retrieveData() {
return repository.retrieveData();
}
}
public interface ExampleRepository {
List<Data> retrieveData();
}
#ApplicationScoped
public class DynamoRepository implements ExampleRepository {
#Override
public List<Data> retrieveData() {
//Get Data from DynamoDb
}
}
#ApplicationScoped
public class CsvRepository implements ExampleRepository {
#Inject
CsvBeanHandler csvBeanHandler;
#Inject
LocalFileReader fileReader;
#Override
public List<Data> retrieveData() {
// Get data from CSV
}
}
I currently also have the following in my application.yml:
com:
example:
application:
storage-type: 'CSV' # OR AMAZON_DYNAMO_DB
It looks like they've added this directly to the documentation:
https://quarkus.io/guides/cdi-reference#declaratively-choose-beans-that-can-be-obtained-by-programmatic-lookup
I feel a bit guilty pasting this much, but it's the SO way.
I can add that it is NOT like a Guice 'binding'; BOTH classes will be instantiated, but only one will be injected. Also unlike Guice, you cannot inject the interface (or I did it wrong) - you have to do what's shown below, with Instance.
Personally I just use constructor injection and then drop the value of the Instance wrapper into a final field, so I'm not crying about the extra step. I do miss the power and explicit bindings possible with Modules ala Guice, but the simplicity here has its own value.
5.16. Declaratively Choose Beans That Can Be Obtained by Programmatic Lookup
It is sometimes useful to narrow down the set of beans that can be
obtained by programmatic lookup via javax.enterprise.inject.Instance.
Typically, a user needs to choose the appropriate implementation of an
interface based on a runtime configuration property.
Imagine that we have two beans implementing the interface
org.acme.Service. You can’t inject the org.acme.Service directly
unless your implementations declare a CDI qualifier. However, you can
inject the Instance instead, then iterate over all
implementations and choose the correct one manually. Alternatively,
you can use the #LookupIfProperty and #LookupUnlessProperty
annotations. #LookupIfProperty indicates that a bean should only be
obtained if a runtime configuration property matches the provided
value. #LookupUnlessProperty, on the other hand, indicates that a bean
should only be obtained if a runtime configuration property does not
match the provided value.
#LookupIfProperty Example
interface Service {
String name();
}
#LookupIfProperty(name = "service.foo.enabled", stringValue = "true")
#ApplicationScoped
class ServiceFoo implements Service {
public String name() {
return "foo";
}
}
#ApplicationScoped
class ServiceBar implements Service {
public String name() {
return "bar";
}
}
#ApplicationScoped
class Client {
#Inject
Instance<Service> service;
void printServiceName() {
// This will print "bar" if the property "service.foo.enabled" is NOT set to "true"
// If "service.foo.enabled" is set to "true" then service.get() would result in an AmbiguousResolutionException
System.out.println(service.get().name());
}
}
If your request is to bind at startup time the right implementation based on a configuration property, I suppose your problem may be resolved used #Produces annotation:
public class ExampleRepositoryFactory {
#Config("storage-type")
String storageType;
#Produces
public ExampleRepository dynamoInstance() {
return storageType == "CSV" ? new CsvRepository() : new DynamoRepository();
}
}
As I know, if the static method from other class, we may interpret their relationship with dependency, just like the answer from How to show usage of static methods UML Class Diagram
However, how about for the static variable from other class? Is it the similar case; using dependancy?
For example,
class A{
public static String CHAR="Charecter";
public static String INT="Integer";
public static String STR="String";
}
class B{
public String Type;
public B(){
Type=STR;
}
public void B(String t){
Type=t;
}
}
would it result in the uml class diagram as below?
Note that although I would rather use enumeration in real life for this case, I just would like to know how it works.
Yes, this is similar.
Dependency shows that one class is "aware" of some other class and uses it in some way (or more generally depends on it). It can for instance refer to (public) static attributes, static operations and so on.
I am trying to use JAXB in an Eclipse project. View widgets are bound to model attributes with java.beans.PropertyChangeSupport. This works fine. I want to also bind model attributes to a persistent XML representation on disk with JAXB. I can marshal important state to XML and can unmarshal that back into a pojo/bean thing at runtime but am not sure how best to proceed.
The bean setters bound to my view widgets need to firePropertyChange() but XJC generates only simple setters, this.value = value.
XJC properties are protected, so it looks like I could override its setters to firePropertyChange(), but I don't know how my overriding subclass could have its unmarshaled superclass magically change state at runtime (like when user requests report for different year which is when I would unmarshal a different XML file).
Is there an example or pattern for doing this? Surely it is not new. Many thanks. -d
#Adam Thanks! I grokked a workable solution with this:
public class MyBean extends JaxBean {
public JaxBean getJaxBean() {
return this;
}
public void setJaxBean(JaxBean jaxBean) {
super.setThis(jaxBean.getThis());
super.setThat(jaxBean.getThat());
// etc...
}
public MyBean() {
// etc...
}
}
I think my confusion was thinking the unmarshalled bean would somehow magically replace my working instance. The solution above requires additional text but it works and the use of JaxBean's dumb setters avoids firing events unnecessarily when loading a new XML.
Your solution, annotating MyBean with JAXB and using schemagen, sounds even better. I will try that next go around. These are very nice technologies. -d
I mentioned another approach to your application in my comment.
It's what we use in our RCP application. Except that we marshall/unmarshall through network thus we use JAXWS and not just JAXB.
I'm somewhat experienced with this kind of stack, so here's a kick-starter for you:
/**
* Your UI POJO-s should extend this class.
*/
public abstract class UIModel<T extends UIModel> {
protected final PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);
/**
* This comes handy at times
*/
public void afterUnmarshal(Unmarshaller unmarshaller, Object parent) {
//....
}
/**
* And this too, trust me.
*/
public void deepCopy(final T of) {
removePropertyChangeListener(propertyChangeListener);
//It's from Spring Framework but you can write your own. Spring is a fat-ass payload for a Java-SE application.
BeanUtils.copyProperties(of, this, IGNORED_ON_CLIENT);
addPropertyChangeListener(propertyChangeListener);
}
}
public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
propertyChangeSupport.addPropertyChangeListener(propertyName, listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
propertyChangeSupport.removePropertyChangeListener(listener);
}
}
/**
* Example of a UI POJO.
*/
public class Car extends UIModel<Car> {
private String make;
private int numberOfWheels;
//... etc.
/**
* Example of a setter
*/
public void setMake(String make) {
propertyChangeSupport.firePropertyChange("make", this.make, this.make = make);
}
public String getMake() {
return make;
}
//... etc.
}
I don't know how often your Schema-definition changes but there's a pattern supporting this;
/**
* New application (compiled with the class below) can open a file saved by the old application.
*/
public class Car2 extends Car {
private String fuelType; // Example of a new field
public void setFuelType(String fuelType) {
propertyChangeSupport.firePropertyChange("fuelType", this.fuelType, this.fuelType = fuelType);
}
//... etc.
}
This way the old application can open XML-outputs of the new. Dropping a field from such a class's source code will result in a RuntimeException as JAXB is still looking for it.
If you're clients are always up-to-date then you should not care about this at all.
When tackling with Java collections and subclassing excessively you will run into JAXB problems which you can solve by Googling #XmlRootElement and #XmlSeeAlso annotations.
Comments don't format, trying "answer". Need to do the stackoverflow tour. Continuing,
Thanks, Adam, I will bookmark these for future reference. They look similar to my example, the pattern is (unmarshal New, be quiet, copy New to Old, be noisy). I like the mind-bending recursion,
class UIModel<T extends UIModel>
class Car extends UIModel<Car>
and assume you've tested it compiles. ;)
Regards, -d.
I wanted to implement the factory pattern with CDI. Here we have the business case example:
A client provides a string representing a type. Depending on this type the factory returns an implementation of an interface.
I know that there are a lot of questions flying around concerning factory pattern and CDI. The difference I have here is that I resolve the implementation returned by the factory based on a runtime parameter.
I was thinking of using a producer method but then I can not think of how to inject the resolved implementation into the bean where the implementation is needed since this is a runtime parameter which is not necessarily known at contruction time.
So I thought of the pretty straight forward way of using the Instance class.
Here is the basic implementation :
// the interface. Instances of this class are returned from the factory
public interface Product {
}
// one implementation may be returned by the factory
#ProductType("default")
public class DefaultProduct implements Product {
}
// another implementation may be returned by the factory
#ProductType("myProduct")
public class MyProduct implements Product {
}
// the qualifier annotation
#Qualifier
#Retention(RetentionPolicy.RUNTIME)
#Target({ElementType.FIELD, ElementType.TYPE})
public #interface ProductType {
String value();
}
// the Annotation implementation to select
// the correct implementation in the factory
public class ProductTypeLiteral extends AnnotationLiteral<ProductType>
implements ProductType {
private String type;
public ProductTypeLiteral(String type) {
this.type = type;
}
#Override
public String value() {
return type;
}
}
// the factory itself. It is annotated with #Singleton because the
// factory is only needed once
#Singleton
public class Factory {
#Inject
#Any
private Instance<Product> products;
public Product getProduct(String type) {
ProductTypeLiteral literal = new ProductTypeLiteral(type);
Instance<Product> typeProducts = products.select(literal);
return typeProducts.get();
}
}
In my opinion using Instance is very sophisticated.
But this has one major drawback:
Everytime you cal the Instance.get() method you retrieve a new Instance of Product. This may be fine but the Instance instance keeps a reference of the returned instance internally. So as long as the Factory lives and each time the Instance.get() is called the more instances of Product will exist in the memory and never get garbage collected because a reference is still hold in Instance.
I thought of not making the Factory a singleton but that just shifts the problem and does not solve it. And of course it is against the factory pattern.
Another solution I tried was to iterate through the Instance instead of selecting an implementation with the help of the annotation:
#Singleton
public class Factory {
#Inject
#Any
private Instance<Product> products;
public Product getProduct(String type) {
Product product = null;
for(Product eachProduct : products) {
ProductType productType = eachProduct.getClass().
getAnnotation(ProductType.class)
if(productType.value().equals(type) {
product = eachProduct;
break;
}
}
return product;
}
}
Basically this is working. Now each time depending on the given type I retrieve the same instance of Product. That way the memory is not consumed.
But I don't like it to iterate over a collection when I have the possibility to resolve the correct implementations more elegantly.
Do you have any ideas which may solve the problem? Otherwise I may have to keep the iteration solution.
Herein lies your problem. Instance keeps reference to instances you obtain from it using get() because it is responsible for reclaiming them when they go out of scope (i.e. when the injected Instance goes out of scope. But because you made your factory a singleton, it will never go out of scope. So, make your factory a short-lived scope, like #RequestScoped or even #Dependent, that way all the returned instances will be reclaimed properly.
Maybe it can help you:
Create qualifiers:
#Qualifier
#Retention(RetentionPolicy.RUNTIME)
#Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.TYPE})
public #interface MyProduct{
}
#Qualifier
#Retention(RetentionPolicy.RUNTIME)
#Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.TYPE})
public #interface DefaultProduct{
}
In Factory class:
#Singleton
public class Factory {
public Product getProduct(#MyProduct MyProduct product, #DefaultProduct DefaultProduct defaultProduct) {
//What you wanna do
}
}
If I have an entity Entity and a service EntityService and EntityServiceFacade with the following interfaces:
interface EntityService {
Entity getEntity(Long id);
}
interface EntityServiceFacade {
EntityDTO getEntity(Long id);
}
I can easily secure the read access to an entity by controlling access to the getEntity method at the service level. But once the facade has a reference to an entity, how can I control write access to it? If I have a saveEntity method and control access at the service (not facade) level like this (with Spring security annotations here):
class EntityServiceImpl implements EntityService {
...
#PreAuthorize("hasPermission(#entity, 'write')")
public void saveEntity(Entity entity) {
repository.store(entity);
}
}
class EntityServiceFacadeImpl implements EntityServiceFacade {
...
#Transactional
public void saveEntity(EntityDTO dto) {
Entity entity = service.getEntity(dto.id);
entity.setName(dto.name);
service.save(entity);
}
}
The problem here is that the access control check happens already after I have changed the name of the entity, so that does not suffice.
How do you guys do it? Do you secure the domain object methods instead?
Thanks
Edit:
If you secure your domain objects, for example with annotations like:
#PreAuthorize("hasPermission(this, 'write')")
public void setName(String name) { this.name = name; }
Am I then breaking the domain model (according to DDD?)
Edit2
I found a thesis on the subject. The conclusion of that thesis says that a good way IS to annotate the domain object methods to secure them. Any thoughts on this?
I wouldn't worry about securing individual entity methods or properties from being modified.
Preventing a user from changing an entity in memory is not always necessary if you can control persistence.
The big gotcha here is UX, you want to inform a user as early as possible that she will probably be unable to persist changes made to that entity. The decision you will need to make is whether it is acceptable to delay the security check until persistence time or if you need to inform a user before (e.g. by deactivating UI elements).
If Entity is an interface, can't you just membrane it?
So if Entity looks like this:
interface Entity {
int getFoo();
void setFoo(int newFoo);
}
create a membrane like
final class ReadOnlyEntity implements Entity {
private final Entity underlying;
ReadOnlyEntity(Entity underlying) { this.underlying = underlying; }
public int getFoo() { return underlying.getFoo(); } // Read methods work
// But deny mutators.
public void setFoo(int newFoo) { throw new UnsupportedOperationException(); }
}
If you annotate read methods, you can use Proxy classes to automatically create membranes that cross multiple classes (so that a get method on a readonly Entity that returns an EntityPart returns a readonly EntityPart).
See deep attenuation in http://en.wikipedia.org/wiki/Object-capability_model for more details on this approach.