zoukankan      html  css  js  c++  java
  • spring4.0之六:Generic Qualifier(泛型限定)

     Spring 4.0已经发布RELEASE版本,不仅支持Java8,而且向下兼容到JavaSE6/JavaEE6,并移出了相关废弃类,新添加如Java8的支持、Groovy式Bean定义DSL、对核心容器进行增强、对Web框架的增强、Websocket模块的实现、测试的增强等。其中两个我一直想要的增强就是:支持泛型依赖注入、对cglib类代理不再要求必须有空参构造器了。具体更新请参考:

    http://docs.spring.io/spring/docs/4.0.0.RELEASE/spring-framework-reference/htmlsingle/#new-in-4.0

    model类:

    package com.dxz.demo.generic.model;
    
    import java.io.Serializable;
    
    public class Organization implements Serializable {
        private Long id;
        private String name;
    }
    package com.dxz.demo.generic.model;
    
    import java.io.Serializable;
    
    public class User implements Serializable {
        private Long id;
        private String name;
        
        public User(Long id, String name) {
            this.id = id;
            this.name = name;
        }
    }

    dao类:

    package com.dxz.demo.generic.dao;
    
    import java.io.Serializable;
    
    public abstract class BaseDao<M extends Serializable> {
        public void save(M m) {
            System.out.println("BaseDao save:" + m);
        }
    }
    
    package com.dxz.demo.generic.dao;
    
    import org.springframework.stereotype.Repository;
    
    import com.dxz.demo.generic.model.Organization;
    
    @Repository  
    public class OrganizationDao extends BaseDao<Organization> {  
    } 
    package com.dxz.demo.generic.dao;
    
    import org.springframework.stereotype.Repository;
    
    import com.dxz.demo.generic.model.User;
    
    @Repository
    public class UserDao extends BaseDao<User> {
    }

    以前Service写法:

    package com.dxz.demo.generic.service.old;
    
    import java.io.Serializable;
    
    import com.dxz.demo.generic.dao.BaseDao;
    
    public abstract class BaseService<M extends Serializable> {
        private BaseDao<M> dao;
    
        public void setDao(BaseDao<M> repository) {
            this.dao = repository;
        }
    
        public void save(M m) {
            System.out.println("old-----");
            dao.save(m);
        }
    }
    
    package com.dxz.demo.generic.service.old;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import com.dxz.demo.generic.dao.OrganizationDao;
    import com.dxz.demo.generic.model.Organization;
    
    @Service
    public class OrganizationService extends BaseService<Organization> {
        @Autowired
        public void setOrganizationRepository(OrganizationDao organizationDao) {
            setDao(organizationDao);
        }
    }
    package com.dxz.demo.generic.service.old;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import com.dxz.demo.generic.dao.UserDao;
    import com.dxz.demo.generic.model.User;
    
    @Service
    public class UserService extends BaseService<User> {
        @Autowired
        public void setUserDao(UserDao userDao) {
            setDao(userDao);
        }
    }

    可以看到,以前必须再写一个setter方法,然后指定注入的具体类型,然后进行注入;

    service泛型Service的写法

    package com.dxz.demo.generic.service.newf;
    
    import java.io.Serializable;
    
    import org.springframework.beans.factory.annotation.Autowired;
    
    import com.dxz.demo.generic.dao.BaseDao;
    
    
    public abstract class BaseService<M extends Serializable> {
        @Autowired
        protected BaseDao<M> dao;
    
        public void save(M m) {
            System.out.println("newf ----");
            dao.save(m);
        }
    }
    package com.dxz.demo.generic.service.newf;
    
    import org.springframework.stereotype.Service;
    
    import com.dxz.demo.generic.model.Organization;
    
    @Service  
    public class GOrganizationService extends BaseService<Organization> {  
    }  
    package com.dxz.demo.generic.service.newf;
    
    import org.springframework.stereotype.Service;
    
    import com.dxz.demo.generic.model.User;
    
    @Service("gUserService")
    public class GUserService extends BaseService<User> {  
    }  
      

    spring对bean的装配类:

    package com.dxz.demo.generic;
    
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    //添加自动扫描注解,basePackages为待注册bean的包路径
    @ComponentScan(basePackages = "com.dxz.demo.generic")
    public class GenericDemoConfiguration {
        public GenericDemoConfiguration() {
            System.out.println("GenericDemoConfiguration容器启动初始化。。。");
        }
    }
    package com.dxz.demo.generic;
    
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.Import;
    
    @Configuration
    @Import(GenericDemoConfiguration.class)
    public class GenericDemoConfig {
    }

    测试类:

    package com.dxz.demo.generic;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    
    import com.dxz.demo.generic.model.User;
    
    public class TestMain {
    
        public static void main(String[] args) {
            // @Configuration注解的spring容器加载方式,用AnnotationConfigApplicationContext替换ClassPathXmlApplicationContext
            ApplicationContext context = new AnnotationConfigApplicationContext(GenericDemoConfig.class);
            com.dxz.demo.generic.service.newf.BaseService service = (com.dxz.demo.generic.service.newf.BaseService)context.getBean("gUserService");
            service.save(new User(1L,"duan"));
            
            com.dxz.demo.generic.service.old.BaseService service2 = (com.dxz.demo.generic.service.old.BaseService)context.getBean("userService");
            service2.save(new User(1L,"duan"));
        }
    
    }

    大家可以看到,现在的写法非常简洁。支持泛型式依赖注入。

     结果:

    这个也是我之前非常想要的一个功能,这样对于那些基本的CRUD式代码,可以简化更多的代码。

    如果大家用过Spring data jpa的话,以后注入的话也可以使用泛型限定式依赖注入 :

    Java代码  收藏代码
    1. @Autowired  
    2. private Repository<User> userRepository;  

     对于泛型依赖注入,最好使用setter注入,这样万一子类想变,比较容易切换。比如https://github.com/zhangkaitao/es,如果有多个实现时,子类可以使用@Qualifier指定使用哪一个。

  • 相关阅读:
    WPF Caliburn 学习笔记(五)HelloCaliburn
    MSDN 教程短片 WPF 20(绑定3ObjectDataProvider)
    MSDN 教程短片 WPF 23(3D动画)
    比赛总结一
    HDU3686 Traffic Real Time Query System
    HDU3954 Level up
    EOJ382 Match Maker
    UESTC1565 Smart Typist
    HDU3578 Greedy Tino
    ZOJ1975 The Sierpinski Fractal
  • 原文地址:https://www.cnblogs.com/duanxz/p/7491190.html
Copyright © 2011-2022 走看看