Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add an annotation @Inject (like Guice) or a @Configurable for a property to inject a spring bean. [SPR-4602] #9279

Closed
spring-projects-issues opened this issue Mar 19, 2008 · 9 comments
Assignees
Labels
in: core Issues in core modules (aop, beans, core, context, expression)

Comments

@spring-projects-issues
Copy link
Collaborator

spring-projects-issues commented Mar 19, 2008

Alexandre Navarro opened SPR-4602 and commented

Add an annotation @Inject (like Guice) or a @Configurable for a property to inject a spring bean.

It is like the @Configurable not for a class but for a property or it is like @Inject annotation in Guice Framework.
The mecanism might be like @Configurable (with aspect) at the creation of the class.
It is not like @Autowired because the bean is not instanciated by the application Context.


Affects: 2.5.2

Attachments:

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented Mar 19, 2008

Alexandre Navarro commented

If you want, I can modify the code of @Configurable to add this feature.

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented Mar 19, 2008

Oleksandr Alesinskyy commented

Can you first specify desired behavior more precisely?

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented Mar 19, 2008

Alexandre Navarro commented

For instance :

I have a class

public class Toto
{
private String a;
private String b;

...
}

I have a Main class

@Configurable
public class Main
{
private static Toto toto;

/**
 * main.
 *
 * @param args
 */
public static void main(String[] args)
{
    ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
    Main main = new Main();
    System.out.println("toto=" + toto);
    System.out.println("main=" + ctx.getBean("main"));
    
}

/**
 * Sets the toto.
 * 
 * @param aToto The toto to set.
 */
public void setToto(Toto aToto)
{
    this.toto = aToto;
}

}

My applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">

<aop:aspectj-autoproxy />

<bean id="toto" class="fr.Toto">
	<property name="a" value="a" />
	<property name="b" value="b" />
</bean>

</beans>

I want the possibility to do that

public class Main
{
@Configurable(autowire=Autowire.BY_NAME)// or (autowire=Autowire.BY_TYPE)
//or @Inject //like Guice
private Toto toto;

...
}

After when I do

Main main = new Main();

the bean toto created by the Application Cotnext will be automatically injected in the property toto.

It is very usefull when you use Spring in main program (like a server standalone or a GUI not a webapp), when you don't want always to use a ServiceLocator like :
(Toto) ServiceLocator .getInstance().getBean("toto");
and you want to check the possibiliy to have a ClassCastException at Buildtime not at Runtime.
Is very close to @Configurable but for a property or like @Autowired but for a bean not instanciated by the Application Context.

If I'm not clear, tell me.

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented Mar 19, 2008

Juergen Hoeller commented

Actually, when you use a plain @Configurable at the type level and then mark specific fields/properties with @Autowired, you should get exactly the behavior that you're describing. In Spring 2.5, @Configurable marks that class as "to be injected once constructed" but doesn't imply the existence of a bean definition; the to-be-injected fields/properties are expected to be marked as @Autowired then. So this should work with Spring 2.5 already!

BTW, Guice's @Inject only works in Guice-managed instances as well, just like Spring's @Autowired. Those two annotations are very similar in usage style and semantics. The differentiator in our case here is Spring's @Configurable which allows @Autowired-driven injection even on instances not managed by the framework.

Juergen

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented Mar 19, 2008

Alexandre Navarro commented

I tried what you said and it seems not to work. Maybe I made a mistake.

This is what I tested.

Main.java

package fr;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/*

  • Created on 11 mars 08

*/
public class Main
{

/**
 * main.
 *
 * @param args
 */
public static void main(String[] args)
{
    ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
    Titi titi = new Titi();
    System.out.println("titi=" + titi);
    
}

}

Titi.java

package fr;
import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;

/*

  • Created on 11 mars 08

*/
@Configurable(autowire=Autowire.BY_NAME)
public class Titi
{
@Autowired
private Toto toto;

/**
 * Returns the toto.
 * 
 * @return The toto to return.
 */
public final Toto getToto()
{
    return this.toto;
}




/**
 * Sets the toto.
 * 
 * @param aToto The toto to set.
 */
public final void setToto(Toto aToto)
{
    this.toto = aToto;
}



/**
 * toString.
 *
 * @return
 */
@Override
public String toString()
{
    return "Titi toto=" + this.toto;
}

}

Toto.java

package fr;

import org.springframework.beans.factory.annotation.Configurable;

/*

  • Created on 11 mars 08

*/
public class Toto
{
private String a;
private String b;

/**
 * Returns the a.
 * 
 * @return The a to return.
 */
public String getA()
{
    return this.a;
}

/**
 * Sets the a.
 * 
 * @param aA The a to set.
 */
public void setA(String aA)
{
    this.a = aA;
}

/**
 * Returns the b.
 * 
 * @return The b to return.
 */
public String getB()
{
    return this.b;
}

/**
 * Sets the b.
 * 
 * @param aB The b to set.
 */
public void setB(String aB)
{
    this.b = aB;
}

/**
 * toString.
 *
 * @return
 */
@Override
public String toString()
{
    return "a=" + this.a + " b=" + this.b;
}

}

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">

<context:annotation-config />
<aop:aspectj-autoproxy />

<bean id="toto" class="fr.Toto">
	<property name="a" value="a" />
	<property name="b" value="b" />
</bean>

</beans>

The result is of a new Titi() is

titi=Titi toto=null

@Autowired seems to work only on bean defined in applicationContext.xml (the reason why I posted).

I let the source if you have time to test.

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented Mar 19, 2008

Juergen Hoeller commented

Are you compiling your classes with the AspectJ compiler or using the AspectJ agent for load-time weaving, applying the Spring-provided spring-aspects.jar? Otherwise your @Configurable annotation will simply be ignored... Since we need to intercept constructor invocation here, AspectJ weaving is mandatory for this to work.

Juergen

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented Mar 20, 2008

Alexandre Navarro commented

You're right. I used the AspectJ agent for load-time weaving but I forgot to add context:load-time-weaver/ in my applicationContext.xml.

Thanks a lot, you make a very good framework with Spring.

You can close the issue.

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented Mar 20, 2008

Juergen Hoeller commented

OK, good to hear that it works for you :-) Thanks for the kind words...

Juergen

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented Mar 20, 2008

Alexandre Navarro commented

I attached my example which works.

@spring-projects-issues spring-projects-issues added type: enhancement A general enhancement in: core Issues in core modules (aop, beans, core, context, expression) labels Jan 11, 2019
@spring-projects-issues spring-projects-issues removed the type: enhancement A general enhancement label Jan 11, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core Issues in core modules (aop, beans, core, context, expression)
Projects
None yet
Development

No branches or pull requests

2 participants