简体   繁体   中英

Manual injection of CDI component into a non managed class Java EE

I have a method in a non-managed class. This method returns an object of another class. Depending on the context (if this class is in a Java EE context or not) it should return a different object. In Java EE context it should return the correct injected instance, if not it should return a proxy.

public class TestHelperConnector {
    public TestHelper getInstance(){
        try {
             // problem: the BeanManager is never found
             BeanManager beanManager = (BeanManager) new InitialContext().lookup("java:comp/BeanManager");
             return beanManager.getBeans(TestHelper.class);
        } catch (NameNotFoundException e) {
            // no bean manager -> no Java EE context (?)
            TestHelper testHelperProxy = ... do jmx connection
            return testHelper;
        }
    }
}

So the proxi is working, but all the time. I never get the instance of the BeanManager. Even if we call from a managed class.

@Stateless
public class Foo {
    public void doIt() {
        // problem: we never get the injected instance, he always creates the proxy
        TestHelper testHelper = new TestHelperConnector().getInstance();
    }
}

Background: We're using a TestHelper class which contains a huge bulk of methods to support tests. This TestHelper is used by unit as well as integration (arquillian) tests and also for acceptance (selenium) tests. The TestHelper is so integrated that it would be a pain to select it manually all the time so we need a way to get the right instance automatically, no matter if we're in Java EE context or not.

System: jBoss 7.1.1.Final

Why don't we get the BeanManager instance? Is there a better way then we do at the moment?

Take a look at the BeanProvider class in DeltaSpike. If I understand everything correctly, we should have something in there that will help you do what you're trying to do.

I found a crappy workaround and I'm not sure if I should even share this ... but it works :)

So, if it runs in the jboss it will load at startup and set its instance to the static variable which is passed by getInstance(). If not this variable will not be initialized and proxy is loaded:

@Singleton
@Startup
public class TestHelperConnector {
    private static TestHelperMBean instance;

    @Inject
    private TestHelperMBean testHelper;

    @PostConstruct
        private void initInjectedTestHelper() {
        instance = testHelper;
    }

    public static TestHelperMBean getInstance() {
        if (instance == null) {
             instance = getProxyInstance();
        }
        return instance;
    }

    private static TestHelperMBean getProxyInstance() {
        // creating proxy ...
        return ...;
    }
}

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