简体   繁体   中英

Unable to use @spring annotations when class object is new

Actually i am having a spring main class as follows.

ClassLoader loader = null;

    try {
        loader = URLClassLoader.newInstance(new URL[]{new   

 File(plugins + "/" + pluginName + "/" + pluginName +   

 ".jar").toURI().toURL()}, getClass().getClassLoader());

    } catch (MalformedURLException e) {
        e.printStackTrace();
    }

 Class<?> clazz = null;

    try {

        clazz = Class.forName("com.sample.Specific", true, loader);

    } catch (ClassNotFoundException e) {

        e.printStackTrace();

    }

Method method = null;
    try {
        method = clazz.getMethod("run",new Class[]{});
    } catch (NoSuchMethodException e) {
        e.printStackTrace();
    }

 try {
        method.invoke(clazz.newinstance,new Object[]{});
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        e.printStackTrace();
    }

Specific Class is follow :

package com.sample
@Service
public class Specific {

    @Autowired
    private FD fd;


    public void run(){

        fd.init();

    }

}

@Autowired FD comes to be null. Can anyone give me some solution as i also know new operator will not work for @autowired . As i am loading class with new instance then only it becomes null. Can anyone guide me in this thing

Add Specific Service bean inside your main class. As long as the service is inside one your component scan packages then you shall be fine. Do not use new operator.

@Autowired
private Specific specific;

Spring has its own way to provide you new objects. As long as you're consistent using @Autowired and @Component/@Service/@Repository/@Controller there should be no problem

And since all "business" object instantiation is handled by Spring you should never use new . If you have no other way of getting an instance (something I realy doubt about it) you can use ApplicationContext.getBean() but as I said, in most cases this is not required (and this is also a bad practice)

If you need several instances of a class instead of injecting them (by using @Autowired ) you can inject a Provider<T>

UPDATE

Since the class is known at runtime you need to inject an ApplicationContext and use it to get the bean:

public class TheClassWhereYouAreCreatingTheObject {

    @Autowired
    private ApplicationContext context;                  // You definitely need this

    public void theMethodWhereYouAreCreatingTheObject() {
         Class<?> clazz = ...                            // getting the object class
         Object instance = context.getBean(clazz);     // getting and instance trough Spring

         // If you know that kind of object you will get cast it at call its methods
         ((Specific) instance).run();

         // If you know anything about the class you will have to use reflection
         Method method = clazz.getMethod("run", new Class[]{});
         method.invoke(instance, new Object[]{});
    }
}

If you want to take advantage of autowiring then I think we have to think from spring terms.

you can use Beanutils to create a new instance and play with reflections supporting spring features. Please go through below methods:

https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/beans/BeanUtils.html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM