Spring autowiring with parameter - java

I am trying to do autowiring using dynamic parameter, I know we can declare a class with #component and make the class available for autowiring, but what if I have a class with parametrized construtor. I can we use autowiring and intialise the object with paramter?
Please see the below snippet.
#Component
public class A{
public A(Object B){
// do something
}
}
public class C{
#Autowire
private A a;
public foo(){
B b = getBfromSomewhere();
// create object of A using parameter B
// like a = new A(b);
}
}

I got the answer after going through the configuration annotation. One should first must tell spring, how it should create the bean for example.
#Configuration
public class Appconfig{
#Bean(name="a")
public A getA(B b){
return A(b);
}
}
Later when you are using it.
public class C{
#Autowire
private BeanFactory factory;
public foo(){
B b = getBfromSomewhere();
A a = factory.getBean(A.class,b)
}
}

Related

Unable to read properties using #Value in SpringBoot application

So I have the following structure
#Component
#RequiredArgsConstructor
ClassA{
ClassB b = new ClassB();
b.printTableName();
}
#Component
#RequiredArgsConstructor
ClassB{
#Value("${com.table}")
private String tableName;
public printTableName(){
System.out.println(tableName);
}
}
The printTableName function always prints null , the tableName in this function is always null . How do I go about fixing this ?
Thank you for the help !
You cannot instance the class manually if you need the spring manage your beans.
Try instance your beans with spring injects
#Component
public class ClassB {
#Value("${com.table1}")
private String valueRequiredOnProperties;
#Value("${com.table2:#{null}}")
private String valueNullByDefaultIfNotInformedOnProperties;
#Value("${com.table3:table_default}")
private String valueByDefaultTableIfNotInformedOnProperties;
public void printTableName(){
System.out.println(valueRequiredOnProperties);
System.out.println(valueNullByDefaultIfNotInformedOnProperties);
System.out.println(valueByDefaultTableIfNotInformedOnProperties);
}
}
#Component
public class ClassA { // you need call this class in controllers, configurations or others ways to spring manager the instances
// it's necessary indicate to spring manage the instance of beans
#Autowired
private ClassB classBManagedBySpring;
public void callPrintClassB(){
ClassB classB = new ClassB();
classBManagedBySpring.printTableName(); // this will work
classB.printTableName(); // this will not work
}
}
your application.properties
com.table1=TABELA_1
# com.table2=
# com.table3=

How to use auto canditate false or exclude bean inside pojo Spring rather than xml?

I have Beans class
class A{
#Autowired
B b;
......
}
Class Config{
#Bean
A a(){
return new A();
}
}
Class Test{
#Autowired
A a;
void doSom(){
a.blabla();
}
public static void main(String[] args){
..........
}
}
My question here,When i inject A in Test class, b also should have the object. else we will get no bean type exception B....So other than required false in autowired, is there any other way to exclude while spring initialize this A class and b should get create based on some conditions .Can you please help or guide how to exclude beans while running Test class

Changing a class annotated #Component to #Bean annotated method

I have a class that is annotated #Component that was then #Autowired into another class. However, I need to remove this #Component annotation and instead, create it with an #Bean annotated method in the class where its was previously autowired.
Where previously the classes looked like:
#Component
public class MyClass implements IMyClass
{
// Stuff
}
#Configuration
public class MyUsingClass
{
#Autowired
private IMyClass myClass;
private void methodUsingMyClass()
{
myClass.doStuff();
}
}
So now I have removed the #Component annotation and written a #Bean annotated method like this:
public class MyClass implements IMyClass
{
// Stuff
}
#Configuration
public class MyUsingClass
{
#Bean
public IMyClass getMyClass()
{
return new MyClass();
}
....
}
My question is around replacing the previous call of myClass.doStuff() to use the new bean. Do I now pass in a parameter of type MyClass to the private method:
private void methodUsingMyClass(final MyClass myClass)
{
myClass.doStuff();
}
... or do I call this method directly (doesn't seem the correct way to me):
private void methodUsingMyClass()
{
getMyClass().doStuff();
}
... or are neither of these correct?
I think you misunderstand the #Bean annotation. It can be used to create a Bean. So basically spring will scan all classes, will find your #Bean and create a Bean, not more. You can now use this bean, like if you would use one created with <bean></bean>. To actually use the bean you need to either get it from ApplicationContext or #Autowire it. Of course you can still use that function like any other function in your code, to create a new instance of that object, but that would contradict to what you want to achieve with beans
Using Annotations that solutions
public class MyClass implements IMyClass{
private OtherClassInjection otherClassInjection;
private OtherClassInjection2 otherClassInjection2;
MyClass(OtherClassInjection otherClassInjection, OtherClassInjection2 otherClassInjection2){
this.otherClassInjection=otherClassInjection;
this.otherClassInjection2=otherClassInjection2;
}
public void useObject(){
otherClassInjection.user();
}
}
#Bean(name = "myClass")
#Autowired
#Scope("prototype") //Define scope as needed
public MyClass getMyClass(#Qualifier("otherClassInjection") OtherClassInjection otherClassInjection,
OtherClassInjection2 otherClassInjection2) throws Exception
{
return new MyClass(otherClassInjection, otherClassInjection2);
}
that logical, it's work injection #Autowired when create a Bean if context are know that bean, that you will to want inject.
I'm use that way.

Spring autowiring issue in spring batch

I seem to be having an issue with the way I have implemented autowiring in my Spring Batch application.For example if I use:
public class A{
#Autowired
BeanList beanList;
}
this works fine for Class A.In the sense that,beanList returns the values that it should.But if from a method from class A I am calling a method from a different class and then have the same
#Autowired
BeanList beanList
,beanList return a null.But autowiring seems to work fine across steps.I have
I'm not sure if I understood your question correctly. I assume, you have something like this:
public class A{
B aB;
#Autowired
BeanList beanList;
public void callToB() { aB.aMethod(); }
}
public class B {
#Autowired
BeanList beanList;
public void aMethod() {Assert.notNull(beanList);}
}
If this is correct, then the problem is likely that you didn't instantiate class B as a "spring bean".
The most simply way to do this would be to mark class B with #Component and to autowire it into class A.
public class A {
#Autowired
B aB;
or to instantiate it with an #Bean directly in class A
#Component
public class A {
#Autowired
BeanList beanList;
#Bean
B myBean() {return new B();}
public void callToB() { myBean().aMethod(); }
Does this describe and solve your problem?

Java configuration in Spring framework

I have classes A, B and their implementation AImpl, BImpl.
interface A {
}
interface B {
}
interface C {
}
class AImpl{
#Inject
AImpl(B b){}
}
class BImpl{
#Inject
BImpl(String foo, C c){}
}
class CImpl{
}
To configure dependencies in Guice I would write smt like
bind(A.class).to(AImpl);
bind(C.class).to(CImpl);
#Provides B provideB(C c){
return new BImpl("foo", c)
}
In spring I can do smt like
#Bean public A a() {
return new AImpl(b())
}
#Bean public B b() {
return new BImpl("foo", c());
}
#Bean public C c() {
return new CImpl();
}
There are several downsides
I should write that AImpl needs B in 2 places (constructor and config).
I should write more code (CImp and AImpl requires method creation instead of one expression)
Are there any way to impruve my spring configuration without doing xml?
upd
I don't want to polute my classes with spring related annotations like #Component either. And I would prefer constructor injection to any kind of other injections. Scanning is not preferable solution too.
So, can I do Spring in Guice way?
upd2
So I want archive
Autowiring
Constructor-injection
Without
XML
PathScan
Instead of creating Bean using java code you can use Autowiring. You can define ComponentScan in your java configuration. You do not need to use any XML file.
This creates beans OK without xml and polluting beans with Spring annotation:
interface A {
}
interface B {
}
interface C {
}
class AImpl implements A {
AImpl(B b) {
}
}
class BImpl implements B {
BImpl(String foo, C c) {
}
}
class CImpl implements C {
}
#Configuration
class Config {
#Bean public A a() {
return new AImpl(b());
}
#Bean public B b() {
return new BImpl("foo", c());
}
#Bean public C c() {
return new CImpl();
}
}
public class T1 {
public static void main(String[] args) throws Exception {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(Config.class);
}
}

Categories

Resources