If you have used JBoss Seam 2 and the later CDI/JBoss Seam 3, you could be impressed of producing generic type bean by the @Factory
(in JBoss Seam 2) or @Produces
annotations.
In CDI projects, you can produces a CDI bean simply.
@Produces List availableConfs;
And inject it in other beans as needed.
@Inject List availableConfs;
But unfortunately, generic type bean injection dose not work in Spring for a long time.
Spring 4 brings partial features of these.
Reuse the former examples.
Conference
and Signup
are JPA entities, and ConferenceRepository
and SignupRepository
are their JpaRepository
implementations.
@Repository public interface ConferenceRepository extends JpaRepository { Conference findBySlug(String slug); } @Repository public interface SignupRepository extends JpaRepository { }
Inject them via JpaRepository
interfaces.
@Autowired JpaRepository conferenceRepository; @Autowired JpaRepository signupRepository;
Some test codes.
@Before @org.springframework.transaction.annotation.Transactional public void beforeTestCase() { log.debug("===================before test====================="); Conference conf=new Conference("Spring One 2014", new Date()); Signup user1=new Signup("Hantsy", "Bai", "[email protected]"); Signup user2=new Signup("Tom", "tom", "[email protected]"); user1.setConference(conf); user2.setConference(conf); conf.getSignups().add(user1); conf.getSignups().add(user2); conferenceRepository.save(conf); } @After @org.springframework.transaction.annotation.Transactional public void afterTestCase() { log.debug("===================after test====================="); signupRepository.deleteAll(); conferenceRepository.deleteAll(); } @Test public void testGenericTypeInjection() { assertTrue(conferenceRepository!=null); assertTrue(signupRepository!=null); assertTrue(conferenceRepository.findAll().size()==1); assertTrue(signupRepository.findAll().size()==2); }
The parameterized type of JpaRepository
worked as a form of qualifiers to identify different implementation classes.
But unfortunately, if you create a generic type bean via @Bean
annotation, and inject it in another bean directly, it will throw an exception which complains the bean is not found.
@Configuration public class AppConfig { @Bean public List availableConfs() { return Arrays.asList(new Conference("JavaOne", new Date()), new Conference("SpringOne", new Date()),new Conference("SpringTwo", new Date())); } }
The following codes will throw an exception.
@Autowired List availableConferences;
But it can be fetched from ApplicaitonContext
.
@Test public void testConfs2() { List confs2=(List )ctx.getBean("availableConferences"); Assert.assertTrue(confs2!=null); Assert.assertTrue(confs2.size()==3); }
As you see, Spring still does not include type-safe bean producing and injection for generic type bean as CDI provides.