How to inject Spring Bean for factory method requi

2019-02-11 20:30发布

问题:

I'm trying to inject a java.util.prefs.Preferences bean in to my master controller. The controller looks like:

@Controller
class MyController {
    @Autowired
    private Preferences preferences;
}

The application-context.xml file creates the bean for java.util.prefs.Preferences. It uses a factory method so I have the following entry for creating the bean:

<bean id="preferences" class="java.util.prefs.Preferences" factory-method="userNodeForPackage" />

Preferences.userNodeForPackage(param) takes for a parameter the class related to the Preference. In this case Spring needs to create the bean by performing the call:

Preferences.userNodeForPackage(MyController.class);

How can a class be passed in to a spring bean instantiated with a factory method? Thanks

Environment information:

Java 7
Spring 3.1

回答1:

You can specify the constructor-arg element

<bean id="preferences" class="java.util.prefs.Preferences" factory-method="userNodeForPackage">
    <constructor-arg type="java.lang.Class" value="com.path.MyController" />
</bean>

This is explained in the official documentation here, section 5.4.1.

Arguments to the static factory method are supplied via elements, exactly the same as if a constructor had actually been used. The type of the class being returned by the factory method does not have to be of the same type as the class that contains the static factory method, although in this example it is. An instance (non-static) factory method would be used in an essentially identical fashion (aside from the use of the factory-bean attribute instead of the class attribute), so details will not be discussed here.



回答2:

Well I don't know the xml based configuration way but I can tell you how you can instantiate it via Configuration class.

@Configuration
public class Config {
    @Bean(name="preferences")
    public java.util.prefs.Preferences preferences() {
        // init
        return java.util.prefs.Preferences.userNodeForPackage(YourExpectedClass.class);
    }
}

P.S. :

You will need to add your configuration class/package for scanning either in web.xml if you are using complete annotation based approach [contextClass=org.springframework.web.context.support.AnnotationConfigWebApplicationContext] or in your config file as below :

<context:component-scan base-package="com.comp.prod.conf" />


回答3:

 public class Preferences
 {  
     SomeBean someBean;

     public void setSomeBean(SomeBean someBean){
            this.someBean = someBean;
     }  

     public static Preferences createSampleBeanWithIntValue(SomeBean someBean)
     {
         Preferences preferences= new Preferences();
         preferences.setSomeBean(someBean);
         return preferences;
     }
}

  <bean id="someBean" class="java.util.prefs.SomeBean"/>

 <bean id="preferences" class="java.util.prefs.Preferences" factory-method="userNodeForPackage" > 

    <constructor-arg ref="someBean "/>       
 </bean>

Please see the reference

http://www.skorks.com/2008/10/are-you-using-the-full-power-of-spring-when-injecting-your-dependencies/



回答4:

first create the bean of 'Preferences' class either using xml file or using annotation.
then you can use this <context:annotation-config> if you created bean using xml configuration to activate the @Autowired annotation functionality
(or )

<context:component-scan base-package="com.estudo.controller" />
if you created bean using annotations.
Note : define the above tags in the spring servlet xml file



回答5:

Spring framework provides facility to inject bean using factory method. To do so, we can use two attributes of bean element.

factory-method: represents the factory method that will be invoked to inject the bean. factory-bean: represents the reference of the bean by which factory method will be invoked. It is used if factory method is non-static. A method that returns instance of a class is called factory method.

public class A {  
public static A getA(){//factory method  
    return new A();  
}  
}  


回答6:

Can you try making "preferences" a property of "MyController". Something like

<bean id="MyController" class="com.your.package.MyController">
    <property name="preferences" ref="preferences" />
</bean>

and then have the getter and setter method for preferences in MyController.

I think this should work.