#Spring 4: Generic type injection

Spring 4: Generic type injection

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.

你可能感兴趣的:(#Spring 4: Generic type injection)