I want to write a function that, given an arbitrary java bean as an argument, returns an object that is a copy of that bean but that belongs to an anonymous subclass of the bean's type that contains an additional property. Let me illustrate with an example of what I have so far:
Foo.java:
import lombok.Data;
import lombol.AllArgsConstructor;
#Data
#AllArgsConstructor
public class Foo {
private String bar;
private String baz;
}
Garply.java:
public class Garply {
Foo fooWithQux(Foo foo, String quxVal) {
return new Foo(foo.bar, foo.baz) {
private String qux;
public String getQux() {
return quxVal;
}
};
}
}
This seems silly because I can never actually call getQux(), but a tool I work with uses reflection to successfully find the qux property and do what I want with it.
My issue is that I don't want to have separate fooWithQux() functions for each type that I want to be able to add the qux property to. Ideally I'd have something like beanWithQux() that accepts objects of arbitrary type. I think I could make this work with something like the following:
public T beanWithQux<T>(T bean, String quxVal) {
class BeanWithQux extends T {
private String qux;
BeanWithQux(T bean, String quxVal) {
// Here's where I'd like to copy all of the properties
// from the Bean into the BeanWithQux
qux = quxVal;
}
public getQux() {
return qux;
}
}
return BeanWithQux(bean, quxVal);
}
Here's where I'm stuck. I don't know to copy all of the properties from the given object into my new object. Anyone have ideas? Ideally there would be something I could do using lombok (I control the Foo class and can add annotations like #Builder if need be) as opposed to writing a bunch of reflection magic myself.
Thanks!
I think in this case using runtime bytecode weaving is a better approach, since you don't need to call the methods in your own codebase.
Related
Consider the existence of a Foo some time in the app. Now Bar objects depend on a Foo. I want to create this bar based on this foo I already have, but Guice creates a new instance of Foo every time. I can have a lot of Foos, so I cannot #Singleton Foo.
I tried to use scopes for this purpose, but I don't know what I am doing wrong.
I know this can be solved with #AssistedInject but I do not want to take this solution because these associations are common in my context and the dependency is only one. Also, since I am working on creating a tool based on Guice, all I got is a Foo, and Bar.class and I want to create instances of Bar with the given Foo. I am not aware if there are any factories or so.
public class InjectionTest2 {
public static void main(String[] args) {
Module module = new AbstractModule() {
ReceiverScope receiverScope = new ReceiverScope();
#Override
protected void configure() {
bindScope(ReceiverScoped.class, receiverScope);
bind(Foo.class);
}
#Provides
#Singleton
public ReceiverScope scope() {
return receiverScope;
}
};
Injector injector = Guice.createInjector(module);
Foo foo = injector.getInstance(Foo.class); //assume a given foo
ReceiverScope scope = injector.getInstance(ReceiverScope.class);
scope.enter();
scope.seed(Key.get(Foo.class, Existing.class), foo);
Bar bar = injector.getInstance(Bar.class);//Create a Bar with this foo
scope.exit();
}
private static class Foo {
#Inject
public Foo() {
System.out.println("foo created" + toString());
}
}
#ReceiverScoped
private static class Bar {
#Inject
public Bar(#Existing Foo foo) {
System.out.println("bar created with foo" + foo.toString());
}
}
#Retention(RetentionPolicy.RUNTIME)
#BindingAnnotation
private static #interface Existing {
}
}
ReceiverScope is a class identical to Simple Scope given here.
Another way I can think of is if I manually iterate Bar's contructor parameters and for each parameter, I ask guice to give me an instance, but if it is a Foo, I give my value. But won't this give me a very hard time? I mean I will have to consider a lot of things, because in the constructor might be extra Qualifiers on parameters and stuff...
EDIT (after #kendavidson's answer):
This is true. I thought it makes my question more complicated, that's why I did not include it. Bar is an interface. Fields in Foo contain an annotation which has a Class<? extends Bar> barClass() method. For example:
#ContainsBars
private static class Foo {
#MakeBar(BlueBar.class)
private Something aSomething;
#MakeBar(BlackBar.class)
private SomethingElse aSomethingElse;
#Inject
public Foo() {
//create aSomething
//create aSomethingElse
}
}
Now, whenever Guice injects a #ContainsBars, I listen it via a TypeListener and I go to create the bars. I scan Foo.class and I get BlueBar.class & BlackBar.class.
The problem I am trying to solve is, how to create BlueBar when BlueBar has a dependency to Foo.class? Whenever this happens, I need to create the BlueBar with the Foo I was taken from the listener.
Reflecting constructor was one of my thoughts however it sounds a pain in the ... I guess, it will need to iterate each parameter of the #Inject constructor of BlueBar.class. If the parameter is of type Foo, I give my Foo. If it is a different type, ask the injector to give me an instance of that type. The thing is, how do I do this. When Guice injects, it takes in consideration possible binding annotations (Qualifiers) and generics. Doing that again, sounds pain.
In the other hand, these #ContainsBars annotated classes by 99% chance have no relation to each other.
Adding a method to Bar interface like setFoo(Foo f) will not work. It will have to be a generic. Therefore, method injection with a setter will be cast unsafe. As far as I am aware of, and assuming BlackBar implements Bar<Foo>, when I will Bar b = injector.getInstance(BlackBar.class), It will give me a Bar<?>. That means, I can't call the setter safely.
Field injection is interesting. Having something like this:
public class BlackBar implements Bar {
private MyDepedency dep;
#Existing
private Foo foo;
public BlackBar(Foo foo,MyDepedency dep) {
this.foo = foo;
this.dep = dep;
}
}
seems ok. Whenever, I get a BlackBar, I go find the #Existing field, and then set the value. I do not care for the value in constructor. Let's say:
Foo foo = ...
Bar bar = injector.getInstance(BlackBar.class);
setExistingFieldWithValueOf(foo,bar);
The problem here is that whenever I ask injector, it sees the Foo dependency, and it is creating a new Foo in order to inject. Then, I go change its value. This will cause an infinite loop since during Foo injection which is a #ContainsBar, the process will be repeated. Even if i manage to stop the infinite loop, still the creation of a new Foo that will never be used seems a bad overhead. If there is a way to inject with null value to foo in the constructor, let me know. I will use this.
This might be a shot in the dark and if I'm missing something please let me know. First off, I definitely think AssistedInject is a solid choice, with a minimal footprint for each Bar.
A couple things missing from your question and comments are:
What are some sample annotated fields of Foo?
How do you expect multiple Bars to be created?
Are you dealing with Bar and OtherBar implementations? Or are you dealing with Bar and <T extends Bar> interface?
Based on some of these things, it might be doable with:
// BarProvider.java
public class BarProvider {
// Get the injector, frowned upon but required
#Inject Injector injector;
public <T extends Bar> T get(Foo foo, String fieldname) {
// Provider right now returns on Bar at a time, I'm guessing this is based on
// fieldname, which can lookup the #Annotation to get the class
Annotation annotation = ...;
Bar bar = ...;
// Now you need to create the bar, this can be done in a couple of ways:
// Option 1 is to reflect the Bar(Foo) constructor
// then doing an injector.injectMembers(bar) to fill the remaining fields
// Option 2 is to use field/method injection and doing a combination of
// Bar bar = injector.getInstance(annotatedClass); followed by
// bar.setFoo(foo);
return bar;
}
}
// Foo.java
public class Foo {
}
// Bar.java
public interface Bar {
}
// ABar.java
public class ABar {
}
// BBar.java
public class BBar {
}
In both cases you would not #Inject the Foo field in Bar. Again this makes some assumptions on how you know which field you want to look at in Foo for the annotation class type.
Another option would be to return all of them using:
public <T extends Bar> T[] get(Foo foo) {
// Same thing but loop through all Annotated fields
}
In both cases I'm assuming that Bar and OtherBar are actually implementations of the same interface which means you'd always be using Bar as a return type. It's still possible otherwise, just a little more annoying.
Hopefully I'm not way off base, and something might be helpful. But again AssistedInject the way it was described above would still probably be a better solution.
Edit 1 - Circular Dependencies
If you have these classes, for example, you will not have issues with Foo being injected and then overwritten.
public abstract class Bar<T> {
T foo;
setFoo(T foo) {
this.foo = foo;
}
}
public class BlackBar extends Bar<Foo> {
#Inject Dep1 dep1; // Injected
#Inject Dep2 dep2; // Injected
BlackBar() {}
}
#ContainsBar
public class Foo {
#BlackBar
SomeObject someObject;
}
Now in your example:
Foo foo = injector.getInstance(Foo.class); // Inject SomeObject
Bar bar = injector.getInstance(BlackBar.class); // Inject Dep1 and Dep2
bar.setFoo(foo); // Set Foo manually
This won't cause the problem you think it does, because Foo foo is NOT annotated with #Inject therefore Guice won't create a new one when building BlackBar.
But this still doesn't answer how exactly you're USING your bars. I also have a feeling I'm missing something very important to the end goal.
#Configuration
public class Product {
#Bean("xyz")
public String getMethod() {
return "abc";
}
}
#Component
public class Test {
String b;
Test(String xyz) {
this.b = xyz;
}
}
Is this any harm with this approach? I am trying to make change in the existing code where I am replacing the #Value with the getter as the method parameter. As I don't want to change the structure of the existing code I am trying to inject the method as bean as a replacement to #Value.
I suggest you to keep the #Value annotation instead of the whole #Bean configurations.
Why?
What if the getMethod()'s returned value needs to be changed very often? Everytime when you're changing something in the Product class, during build time it needs to be recompiled. What happens if the project is getting bigger and you're using this approach? It leads to longer build time and the more important thing is that this solution is not intuitive and it's hard to keep it clean. Don't think about complex solutions only to make the code look fancy. When you need to inject String values, the easiest approach is to create properties files (which won't get recompiled) and use the #Value annotation.
Now, if you want to add new methods without changing the structure of the existing code there are some patterns which you can apply like decorator pattern.
The main idea is simple: you're creating a decorator class which has an object of the type you need.
The easiest example (which you'll find everywhere on the internet) is the classic Shape example:
public interface Shape {
String someMethod();
}
#Component
public class CustomShape implements Shape { //implement the method here }
And here is the decorator:
public interface ShapeDecorator {
String someMethodExtended();
void someExtraMethod();
}
#Component
public class CustomShapeDecorator implements ShapeDecorator{
#Autowired
// #Qualifier - optional (only if you have more Shape implementations)
private Shape shape;
// now you can either:
// 1. provide new methods
#Override
public void someExtraMethod(){
System.out.println("Hello world!");
}
// 2. or you can EXTEND the Shape's "someMethod()" implementation
#Override
public String someMethodExtended(){
String oldString = this.shape.someMethod();
return oldString + " EXTENDED";
}
}
i want to exclude specific properties of spring rest response body. after hours of googling around i found this: http://www.jroller.com/RickHigh/entry/filtering_json_feeds_from_spring due to its date i like to ask if there is something more up-to-date for jackson and or fasterxml. JsonView doesnt fit my requirements as i need to have such case covered:
if A is the set of all my attributes: one time i need to expose B with B ⊂ A. another time C with C ⊂ A. And B ∩ C != ∅
this would cause complex view declarations as well as annotating every class and might not be possible as well in some cases. so what i would like to do is something similar to this:
#RequestMapping("/test1")
#JsonIgnoreProperties( { "property1"})
public TestObject test1(HttpRequest request){
return new TestObject();
}
#RequestMapping("/test2")
#JsonIgnoreProperties( { "property2"})
public TestObject test1(HttpRequest request){
return new TestObject();
}
with output:
{property2:ipsum,property3:dolor}
{property1:lorem,property3:dolor}
In my opinion Jackson View is what you need.
You have to define three interfaces which should cover all properties:
Public - all common properties.
A - properties which belong to set A.
B - properties which belong to set B.
Example interfaces:
class Views {
static class Public { }
static class A extends Public { }
static class B extends Public { }
}
Assume that your POJO class looks like this:
class TestObject {
#JsonView(Views.A.class) String property1;
#JsonView(Views.B.class) String property2;
#JsonView(Views.Public.class) String property3;
}
Now, your controller should contain below methods with annotations:
#RequestMapping("/test1")
#JsonView(Views.B.class)
public TestObject test1(HttpRequest request){
return new TestObject();
}
#RequestMapping("/test2")
#JsonView(Views.A.class)
public TestObject test2(HttpRequest request){
return new TestObject();
}
All of this I has created without testing. Only by reading documentation but it should work for you. I am sure that similar solution worked for me once.
I have below the class.
SomeClass.java
public class SomeClass {
private String name;
private String id;
private String access;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getAccess() {
return access;
}
public void setAccess(String access) {
this.access = access;
}
public void doSomeFunctionality(){
//does some logic using name and id
}
}
Now I have to expose only few methods of above class to clients. I can do as below.
SomeOtherClass.java
public class SomeOtherClass {
private SomeClass someClass = new SomeClass();
public void setName(String name) {
someClass.setName(name);
}
public void setId(String id) {
this.setId(id);
}
}
By doing like above i can restrict one method not accessible to clients and am exposing only required methods. Now client instantiates SomeClass and populates the data into someClass property of SomeOtherClass.java.
But now how can i get the populated data from SomeOtherClass.java?
public SomeClass getSomeClass() {
return someClass;
}
If i provide getter method to get SomeClass in SomeOtherClass.java like above then even clients can also access it which i dont want to do.
But if i can get populated someClass instance directly then i can simply call doSomeFunctionality() on the same instance. like getSomeClass().doSomeFunctionality();
How can i overcome above scenario?
Thanks!
Your question seems confused, but I think this is the answer you are looking for,
Your approach to letting the client get the information should be exactly the same as letting them set it. You should not provide access to the inner SomeClass - that defeats the whole point. So if you want to provide both read and write access to only the name property, your outer class should look like:
public class SomeOtherClass {
private SomeClass someClass = new SomeClass();
public void setName(String name) {
someClass.setName(name);
}
public String getName() {
return someClass.getName();
}
}
You don't have to make the properties they can get the same as the properties they can set. You could also allow them to 'get' the ID, for example, but not set it. If you want them to have access to all the properties, provide getters for all properties in SomeOtherClass. If that is the case you might want to consider creating an interface which specifies all the getter methods and is implemented by both SomeClass and SomeOtherClass, with both classes also implementing the setter methods they require.
There are other architectural approaches if you always want to provide full 'read' access but restricted 'write' access, which we can go into if you ask.
If you create an interface that is implemented by the class that will be used by the client, but then the client obtains its reference to the instantiation of the class using the interface, even if you have public properties, members, ...etc., the client will only see those provided/defined by the interface.
Don't return the SomeClass object in a getter, just create a getter for the field(s) you want to make available:
public String getName() {
return someClass.getName();
}
I would suggest thinking about how you would separately test the pieces involved here. If we look at SomeOtherClass, right away we notice that it has a dependency on SomeClass--this is fine. Unfortunately, you hardwire the dependency to SomeClass by using the new operator. If you used a dependency injection framework (e.g., Spring or Guice) you could simply have the framework provide a fully configured instance of SomeClass to SomeOtherClass so that the instance could be used directly and SomeClass is no longer in the business of creating its own dependencies, but rather it goes about doing its useful work. Calling new on SomeClass in SomeOtherClass impedes your ability to test SomeOtherClass independently of SomeClass--you'll be integration testing unless you employ something like PowerMock, which really is better used in emergency situations like when you can't control third-party code. Hope it helps! P.S. all those setters and none for your dependency on SomeClass!
I've been playing with annotations, and I'm wondering how to go about doing this. What I'd like to do is to be able to have a field declared in a class and annotated such that the field will be initialized with a static instance of the class.
Given an annotation like this:
#Target(ElementType.FIELD)
#Retention(RetentionPolicy.RUNTIME) //or would this be RetentionPolicy.CLASS?
public #interface SetThisField {
}
Something like this:
public class Foo {
#SetThisField
private Bar bar;
}
I've played around with using a parser and setting this at runtime, which works but isn't as elegant as I'd like.
I can't find any really good examples of RetentionPolicy.CLASS but the documentation seems to indicate that I could somehow make the declaration of "bar" get compiled into this:
private Bar bar = Bar.getInstance();
It wouldn't look that way in the source code of course, but it would in the byte code and it would behave like that at runtime.
So am I off base here? Is this possible? Or is the parser the way to go with it?
UPDATE: This is the guts of the parser I'm using
public static void parse(Object instance) throws Exception {
Field[] fields = instance.getClass().getDeclaredFields();
for (Field field : fields) {
//"Property" annotated fields get set to an application.properties value
//using the value of the annotation as the key into the properties
if (field.isAnnotationPresent(Property.class)) {
Property property = field.getAnnotation(Property.class);
String value = property.value();
if (!"".equals(value)) {
setFieldValue(instance, field, properties.getProperty(value));
}
}
//"Resource" annotated fields get static instances of the class allocated
//based upon the type of the field.
if (field.isAnnotationPresent(Resource.class)) {
String name = field.getType().getName();
setFieldValue(instance, field, MyApplication.getResources().get(name));
}
}
}
private static void setFieldValue(Object instance, Field field, Object value) throws IllegalAccessException {
boolean accessibleState = field.isAccessible();
field.setAccessible(true);
field.set(instance, value);
field.setAccessible(accessibleState);
}
I would suggest doing the replacement at run time. This is much simpler to implement and test. Changing the byte code at build time is relatively error prone and tricky to get right. For example you would need to understand how byte code is structured and in this case how to add the code to all the constructors in the right place in the code.
If you make the retention RUNTIME, you can have a library which examines the annotation and sets the value after the object is created.