Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>If you have access to the spring context, you can retrieve an AutowireCapableBeanFactory which you can then use on any bean like this:</p> <pre><code>ApplicationContext springContext = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContextEvent.getServletContext()); AutowireCapableBeanFactory factory = springContext.get(AutowireCapableBeanFactory.class); // this would instantiate and autowire a bean: UserDAO userDAO = factory.createBean(UserDAO.class); // this will autowire an already existing bean: UserDAO manualUserDAO = new UserDAO(); factory.initializeBean(manualUserDAO, "beanNameIfNeeded"); </code></pre> <p>However, if a bean requires that it be autowired before it can be used, I prefer to use the first mechanism and mark the constructor as private/protected to make sure that it cannot be created via 'new' and force it to be created via a factory like above.</p> <p><strong>UPDATE 11/27/17</strong></p> <p>I personally didn't like to have to use the factory every time I wanted to create an autowired instance. Particularly if some other process was creating the instance, such as deserializing from a database, etc.</p> <p>I ended up creating a aspect to automatically handle the autowiring.</p> <p>First, I created an annotation to flag classes that I wanted automatically autowired:</p> <pre><code>@Documented @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Inherited public @interface AutowireAfterCreation { } </code></pre> <p>Then I created an aspect that uses an 'after construction' point cut to do the autowiring. Unfortunately, I was unable to figure out a point cut that was only called after the 'last' constructor was finished, but it doesn't seem to hurt to autowire multiple times, at least in my case.</p> <pre><code>public aspect AutowiringAfterCreation { @Autowired private AutowireCapableBeanFactory beanFactory; /** * After construction, autowire the instance. * @param o Newly created object to be autowired. */ after(Object o) returning : target(o) &amp;&amp; initialization((@AutowireAfterCreation *).new(..)) { // this aspect will actually autowire the instance multiple times if the class is part of an inheritance // Hierarchy. This is not optimal, but it should not hurt anything to autowire more than once. // FUTURE: modify the aspect so it only runs once, regardless of how many constructor calls are necessary. beanFactory.autowireBeanProperties(o, AutowireCapableBeanFactory.AUTOWIRE_NO, false); beanFactory.initializeBean(o, "unused"); } } </code></pre> <p>Then I had to tell Spring about the aspect so the factoryBean is autowired into the aspect itself:</p> <pre><code>&lt;bean class="AutowiringOnDemand" factory-method="aspectOf"/&gt; </code></pre> <p>Now I can create any instance and have it automatically autowired simply by attaching the annotation:</p> <pre><code>@AutowireAfterCreation public class TestEntity { @Value("${some.config.value}") private String value; @Autowired private TestRepository repository; } </code></pre> <p>Finally, all you have to do is create an instance, and it is automatically autowired after the completion of the constructors:</p> <pre><code>TestEntity entity = new TestEntity(); </code></pre> <p><strong>UPDATE 1/2/2018</strong></p> <p>The interface ApplicationContext has changed, and get() has been removed, but you can still use the first mechanism, but you need to call getAutowireCapableBeanFactory() instead.</p> <p>So the first two lines in the example at the top for this answer would now look like:</p> <pre><code>ApplicationContext springContext = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContextEvent.getServletContext()); AutowireCapableBeanFactory factory = springContext.getAutowireCapableBeanFactory(); </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload