I'm playing with java standard CDI and there is one concept I cannot get my head around. In the example below the Application class "requires" the Person class which cannot be injected since it has non-zero args constructor. How should I handle this scenario with CDI?
#Default
class Person {
private String name;
Person(String name) {
this.name=name;
}
String getName() {
return this.name;
}
}
class Application {
#Inject
public Application(Instance<Person> p)
}
There are three ways to inject objects without a no-args constructor. One is to use a producer to create the object.
#Produces
private Person producePerson() {
return new Person(name);
}
The second is to annotate one of the constructors with #Inject and make sure all of the parameters are valid injection targets.
class Person {
private String name;
#Inject
Person(String name) {
this.name=name;
}
String getName() {
return this.name;
}
}
and somewhere else:
#Produces
private String producePersonName() {
return name;
}
(Setting up multiple of these kinds of injections may require creating some qualifier annotations)
The third is to mess around with CDI container initialization with a custom extension, but that is overkill for such a relatively simple need.
Related
assume there is a class Person
class Person{
private Address add;
}
class Address{
String street;
}
The moment I create a bean of Person class then I need a person bean to have address property with value street as "baker lane". Is it possible to use autowire in Person class to achieve this or it cannot be achieved at all?
This was an interview question by the way
we can set default value in Spring expression
#{expression?:default value}
//set deafult value for street
#Value("#{address.street ?: 'baker lane'}")
private String street;
You can use Autowiring on your constructor and modify the behavior of person.
Your interviewer probably expected the following to be explained
#Component
class Person{
private Address add;
#Autowired
public Person(Address add) { <--- An instance of Address will be injected here
this.add = add;
//this.add.setStreet("Custom Street"); <--- you can modify that here before the Autowiring constructor ends
/* if (add.getStreet().isEmpty()) { <--- you can do whatever you want inside the constructor
add.setStreet("Should not be empty") <--- you can check conditionally and set everything you want
} */
}
}
#Component
class Address{
String street;
}
I am creating two constructor for my jersey resource, however only one is the one being able to call,
here is the sample code,
public class jerseyresoure {
private String name;
private int age;
#Inject
public jerseyresoure (String name){
this.name = name;
}
#Inject
public jerseyresoure (int age){
this.age= age;
}
}
the get cosntructor with the parameter int is the one being called successfully,
can you help me with this scenario?
According to the CDI specification it is illegal to annotate more than one constructor with #Inject (see section 3.9 of the CDI specification):
If a bean class does not explicitly declare a constructor using #Inject, the constructor that accepts no parameters is the bean
constructor.
If a bean class has more than one constructor annotated #Inject, the container automatically detects the problem and treats it
as a definition error.
A bean constructor may have any number of parameters. All parameters of a bean constructor are injection points.
So what you can do is as follows:
public class jerseyresoure {
private String name;
private int age;
#Inject
public jerseyresoure (String name, int age){
this.name = name;
this.age = age;
}
}
I assume you are using a producer method so that values (name and age) get injected.
Is there any way to use JAXB annotations on default methods inherited from Java 8 interfaces?
I created a sample maven project at https://github.com/ruckc/jaxb-java8-javafx highlighting the shims required for what I would like to do.
In dealing with JavaFX properties, i've found that I can use the default methods on interfaces to remove the annoying getters/setters from the data object.
public interface Named {
#XmlAttribute(name="name")
default String getName() {
return nameProperty().get();
}
default void setName(String name) {
nameProperty().set(name);
}
StringProperty nameProperty();
}
This removes alot of redundant code inside the implementations. My issue is that now, when trying to marshall the objects using JAXB, I still have to implement the methods (annotated with #Shim) in the implementations, so that the annotations are picked up.
#XmlRootElement(name="business")
public class Business implements Named {
private final StringProperty nameProperty = new SimpleStringProperty();
#Shim
#Override
public void setName(String name) {
Named.super.setName(name);
}
#Shim
#XmlAttribute(name="name")
#Override
public String getName() {
return Named.super.getName();
}
#Override
public StringProperty nameProperty() {
return nameProperty;
}
}
In short, if I remove the #Shim the printed out xml from the main method doesn't contain the name attribute, and the printed out name attribute from the unmarshalled string is null. I'd really like avoiding spurious/duplicate code.
I'm looking for an eclipse plugin that can generate fluent API methods in my beans.
For instance, given this bean:
public class MyBean {
private String name;
private int age;
//Setters and getters
}
Is there any eclipse plugin that generates these methods for me?
public class MyBean {
private String name;
private int age;
public MyBean withName(String name) {
setName(name);
return this;
}
public MyBean withAge(int age) {
setAge(age);
return this;
}
//Setters and getters
}
I've found a google plugin that generates Builder objects, but I prefer fluent API inside each Bean class.
While can't find anything, you can do like me.
Generate the setters, then "Find" (checking "regular expressions") for:
\tpublic void set(.+)\((.+)\) \{\R\t\tthis\.(.+) = (.+);\R\t\}
 and replace with:
\tpublic [PUT_TYPE_HERE] with$1\($2\) \{\R\t\tthis\.$3 = $4;\R\t\treturn this;\R\t\}
Probably there's a simpler expression, but this works ;)
[UPDATE] # 07-MAR-2018
I'm now using lombok which generates getters, setters and builders throught simple annotations. (#Getter, #Setter and #Builder respectively)
It can generate with methods using the #Wither annotation too, but unfortunately its an experimental feature so it should be avoided.
I have an enum and I need to inject it with spring bean.
my enum is:
public enum Status {
IN_PROCESS(1,"In process"),
DONE(0,"Successful"),
CANNOT_DONE(2,"Unsuccessful");
private final int code;
private final String description;
private Status(int code, String description){
this.code = code;
this.description = description;
}
public int getCode() {
return code;
}
public String getDescription() {
return description;
}
}
what my bean.xml should look like for this enum..
thanks.
You can not create an Enum via its constructor from outside of this Enum (not in java and not in Spring) because Enum values are constants!
An Enum constructor can only be invoked from the Enum declarion itselve.
Of course you can use an instance of this Enum, even in Spring, but you can not create it:
public Class Entity {
public Entity(Status status) {...}
}
<bean name="entity" class="package.Entity">
<property name="status" value="IN_PROCESS" />
</bean>
Technically you may try to register enum as a bean like this:
#Configuration
class EnumProducer {
#Bean
Status inProgress() {
return Status.IN_PROGRESS;
}
}
and then inject it like:
#Autowired("inProgress") Status status.
But there is no any sense for doing it.
Check <util:constant/> here:
http://static.springsource.org/spring/docs/3.0.x/reference/xsd-config.html