`

Spring动态创建bean

阅读更多
最近有个项目场景,多垂类支持,大体业务流程相同,只是一些业务规则的校验参数不同。解决思路是将业务参数作为类的属性,然后创建垂类数量个实例,去处理不同垂类的业务。

看了spring ioc部分的代码,个人感觉在spring完成bean创建的过程后,做一个类实现ApplicationContextAware接口,然后克隆多个需要的BeanDefinition,附不同的业务参数属性值的方式比较讨巧。新增加的BeanDefinition会在getBean的过程中,由spring创建。

下面分两部分介绍:
1、动态创建bean的代码实现
2、spring的ioc源码解读,这部分放到另外一篇博客http://mazhen2010.iteye.com/blog/2283773
<spring.version>4.0.6.RELEASE</spring.version>

【动态创建bean的代码实现】
1、创建一个实现ApplicationContextAware接口的类,然后获取DefaultListableBeanFactory
    private void setSpringFactory(ApplicationContext applicationContext) {

        if (applicationContext instanceof AbstractRefreshableApplicationContext) {
            // suit both XmlWebApplicationContext and ClassPathXmlApplicationContext
            AbstractRefreshableApplicationContext springContext = (AbstractRefreshableApplicationContext) applicationContext;
            if (!(springContext.getBeanFactory() instanceof DefaultListableBeanFactory)) {
                LOGGER.error("No suitable bean factory! The current factory class is {}",
                        springContext.getBeanFactory().getClass());
            }
            springFactory = (DefaultListableBeanFactory) springContext.getBeanFactory();
        } else if (applicationContext instanceof GenericApplicationContext) {
            // suit GenericApplicationContext
            GenericApplicationContext springContext = (GenericApplicationContext) applicationContext;
            springFactory = springContext.getDefaultListableBeanFactory();
        } else {
            LOGGER.error("No suitable application context! The current context class is {}",
                    applicationContext.getClass());
        }
    }


2、定义注解,以找到需要克隆的BeaDefinition和需要赋值的属性
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface TemplateService {

    //服务名称
    String serviceName();
    //服务实现名称
    String value() default "";
}

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface TemplateBizParam {
}

@TemplateService(serviceName = "demoService", value = "demoServiceImpl")
public class DemoServiceImpl extends AbstractServiceImpl implements DemoService {

    @TemplateBizParam
    private String noVisitDays;

    @Override
    public void doDemo(Long poiId) {
        StringBuilder builder = new StringBuilder("doDemo").append("//").append("poiId:").append(poiId);
        builder.append("//").append(noVisitDays).append("//").append(getExtendFields()).append("//");
        builder.append("abc:").append(getExtendField("abc"));
        System.out.println(builder.toString());
    }

    @Override
    public void doDemos(List<Long> poiIds) {
        System.out.println("poiIds" + poiIds + "; noVisitDays:" + noVisitDays);
    }

}


3、从垂类模板中获取需要动态创建的bean信息,然后注册BeanDefinition
    private void registerBeanDefinition(String templateId, ServiceEntity serviceEntity) {

        try {
            if (springFactory.containsBeanDefinition(serviceEntity.getImplName())) {
                //step1: 注入多个实例
                String beanKey = generateTemplateBeanName(templateId, serviceEntity.getServiceName());
                BeanDefinition beanDefinition = springFactory.getBeanDefinition(serviceEntity.getImplName());
                String className = beanDefinition.getBeanClassName();
                Class c = null;
                try {
                    c = Class.forName(className);
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                }

                BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.rootBeanDefinition(className);
                beanDefinitionBuilder.getBeanDefinition().setAttribute("id", beanKey);

                springFactory.registerBeanDefinition(
                        beanKey, beanDefinitionBuilder.getBeanDefinition());
                LOGGER.info("Register bean definition successfully. beanName:{}, implName:{}",
                        generateTemplateBeanName(templateId, serviceEntity.getServiceName()), serviceEntity.getImplName());

                //step2: 为实例自动化注入属性
                Object bean = springFactory.getBean(beanKey, c);
                injectParamVaules(bean, c, serviceEntity);
            }

        } catch (NoSuchBeanDefinitionException ex) {
            LOGGER.info("No bean definition in spring factory. implName:{}", serviceEntity.getImplName());
        } catch (BeanDefinitionStoreException ex) {
            LOGGER.info("Register bean definition wrong. beanName:{}, implName:{}",
                    generateTemplateBeanName(templateId, serviceEntity.getServiceName()), serviceEntity.getImplName());
        }
    }

    private <T> void injectParamVaules(Object bean, Class<T> requiredType, ServiceEntity serviceEntity) {

        if (requiredType.isAnnotationPresent(TemplateService.class)) {
            Field[] fields = requiredType.getDeclaredFields(); //获取类的所有属性
            for (Field field : fields) {
                // 注入业务参数
                if (field.isAnnotationPresent(TemplateBizParam.class)) {
                    field.setAccessible(true);
                    try {
                        if ((serviceEntity.getBizParamMap() != null) && (serviceEntity.getBizParamMap().containsKey(field.getName()))) {
                            field.set(bean, serviceEntity.getBizParamMap().get(field.getName()));
                            LOGGER.info("inject biz param value successfully, paramName = {}, value = {}", field.getName(), serviceEntity.getBizParamMap().get(field.getName()));
                        }
                    } catch (IllegalAccessException e) {
                        LOGGER.error("inject biz param failed. {}", e.getMessage());
                        e.printStackTrace();
                    }
                }
            }

            Class<AbstractService> superClass = getSuperClass(requiredType);
            if(superClass != null) {
                Field[] superFields = superClass.getDeclaredFields(); //获取类的所有属性
                for (Field field : superFields) {
                    // 注入扩展字段
                    if (field.isAnnotationPresent(TemplateExtendFields.class)) {
                        field.setAccessible(true);
                        try {
                            if(serviceEntity.getExtendFields() != null){
                                field.set(bean, serviceEntity.getExtendFields());
                                LOGGER.info("inject extend fields successfully, extendFields = {}", serviceEntity.getExtendFields());
                            }
                        } catch (IllegalAccessException e) {
                            LOGGER.error("inject extend fields failed. {}", e.getMessage());
                            e.printStackTrace();
                        }
                    }
                }
            }


        }
    }


4、定义一个Context继承AbstractServiceContext,实现运行时根据策略,选取所需的业务实例进行处理
@Service("demoService")
public class DemoServiceContext extends AbstractServiceContext implements DemoService {

    @Override
    public void doDemo(Long poiId) {
        getServiceImpl(poiId, DemoService.class).doDemo(poiId);
    }

}

/**
 * 服务上下文抽象类,负责具体服务实现类的策略选择和扩展字段传递.
 * User: mazhen01
 * Date: 2016/3/3
 * Time: 10:14
 */
public abstract class AbstractServiceContext {

    @Resource
    private TemplateBeanFactory templateBeanFactory;

    @Autowired
    public TemplateFunction templateFunction;

    // 当前线程使用的beanName
    private ThreadLocal<String> currentTemplateBeanName = new ThreadLocal<String>();

    private static final Logger LOGGER = LoggerFactory.getLogger(AbstractServiceContext.class);

    /**
     * 根据POI所属行业,获取服务实例
     *
     * @param poiId poiId
     * @param clazz 服务接口
     * @param <T>   实例类型
     * @return
     * @throws AnnotationException
     * @throws BeansException
     */
    protected <T> T getServiceImpl(Long poiId, Class<T> clazz) throws AnnotationException, BeansException {
        String serviceName = getServiceName();
        String templateId = templateFunction.getTemplateId(poiId, serviceName);
        if (templateId == null) {
            LOGGER.error("templateId is null. No templateId id configured for poiId = {}.", poiId);
            throw new TemplateException("templateId is null, can not find templateId.");
        }
        currentTemplateBeanName.set(TemplateBeanFactory.generateTemplateBeanName(templateId, serviceName));
        return templateBeanFactory.getBean(TemplateBeanFactory.generateTemplateBeanName(templateId, serviceName), clazz);
    }

    protected <T> T getServiceImpl(List<Long> poiIds, Class<T> clazz) throws AnnotationException, BeansException {
        if (CollectionUtils.isEmpty(poiIds)) {
            LOGGER.error("poiIds List is null");
            throw new TemplateException("poiIds is null.");
        }
        Long poiId = poiIds.get(0);
        return getServiceImpl(poiId, clazz);
    }

    /**
     * 根据beanName,获取服务实例
     *
     * @param templateBeanName beanName
     * @param clazz            服务接口
     * @param <T>              实例类型
     * @return
     * @throws AnnotationException
     * @throws BeansException
     */
    protected <T> T getServiceImpl(String templateBeanName, Class<T> clazz) throws AnnotationException, BeansException {
        return templateBeanFactory.getBean(templateBeanName, clazz);
    }

    /**
     * 根据POI所属行业,获取服务实例的扩展字段列表
     *
     * @param poiId
     * @return
     */
    public List<String> getExtendFields(Long poiId) {
        AbstractServiceImpl abstractService = getServiceImpl(poiId, AbstractServiceImpl.class);

        if (abstractService == null || CollectionUtils.isEmpty(abstractService.getExtendFields())) {
            Lists.newArrayList();
        }

        return abstractService.getExtendFields();
    }

    /**
     * 根据POI所属行业,设置服务实例所需要的扩展字段的具体值
     *
     * @param poiId   poiId
     * @param request 用户请求
     */
    public void setExtendField(Long poiId, HttpServletRequest request) {

        if (request == null) {
            return;
        }

        AbstractServiceImpl abstractService = getServiceImpl(poiId, AbstractServiceImpl.class);

        if (abstractService == null || CollectionUtils.isEmpty(abstractService.getExtendFields())) {
            return;
        }

        for (String field : abstractService.getExtendFields()) {
            setExtendField(field, request.getAttribute(field));
        }
    }

    /**
     * 对扩展字段进行赋值
     *
     * @param field 字段名
     * @param value 值
     */
    public void setExtendField(String field, Object value) {
        if (currentTemplateBeanName == null || StringUtils.isEmpty(currentTemplateBeanName.get())) {
            return;
        }
        AbstractServiceImpl abstractService = getServiceImpl(currentTemplateBeanName.get(), AbstractServiceImpl.class);
        abstractService.getExtendFieldMap().put(field, value);
    }

    protected String getServiceName() throws AnnotationException {

        Class serviceClass = this.getClass();

        if (serviceClass.isAnnotationPresent(Service.class)) {
            Service service = this.getClass().getAnnotation(Service.class);
            if (service != null) {
                return service.value();
            }
            throwException("Has no Service annotation.");
        }

        if (serviceClass.isAnnotationPresent(Component.class)) {
            Component component = this.getClass().getAnnotation(Component.class);
            if (component != null) {
                return component.value();
            }
            throwException("Has no Component annotation.");
        }

        LOGGER.error("Has no annotation.");
        return null;
    }

    /**
     * 根据品类模板,对poiId进行分组
     *
     * @param poiIds
     * @return
     */
    public Map<Long, List<Long>> groupPoiIds(List<Long> poiIds) {
        Map<Long, List<Long>> map = null;
        map = templateFunction.groupPoiIds(poiIds);
        return map;
    }

    private void throwException(String message) throws AnnotationException {
        message = this.getClass() + "||" + message;
        LOGGER.error(message);
        throw new AnnotationException(message);
    }

}


5、在springContext.xml中声明TemplateBeanFactory
<bean class="com.baidu.nuomi.tpl.spring.TemplateBeanFactory"/>

TemplateBeanFactory的完整代码,包括模板变化时的刷新
/**
 * Bean工厂,创建在模板中定义的服务实例,填充业务参数和扩展字段
 * 定时刷新,如发现模板定义中的服务有变化,则刷新spring上下文中的实例.
 * User: mazhen01
 * Date: 2016/3/1
 * Time: 16:46
 */
public class TemplateBeanFactory implements ApplicationContextAware {

    private DefaultListableBeanFactory springFactory;

    private static final Logger LOGGER = LoggerFactory.getLogger(TemplateBeanFactory.class);

    @Autowired
    TemplateFunction templateFunction;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        setSpringFactory(applicationContext);
        templateFunction.init();
        loadTemplateBeanDefinitions(templateFunction.getAllTemplateEntity());
    }

    /**
     * 刷新模板bean
     */
    public void refreshTemplateBeans(List<TemplateEntity> changedTemplates) {
        LOGGER.info("Refresh changed template beans start.");
        if(CollectionUtils.isEmpty(changedTemplates)){
            LOGGER.info("no template beans is changed");
            return;
        }
        destroyTemplateBeans(changedTemplates);
        loadTemplateBeanDefinitions(changedTemplates);
        LOGGER.info("Refresh changed template beans end.");
    }

    /**
     * 根据应用使用的不同applicationContext,获取BeanFactory
     *
     * @param applicationContext 应用使用的applicationContext
     */
    private void setSpringFactory(ApplicationContext applicationContext) {

        if (applicationContext instanceof AbstractRefreshableApplicationContext) {
            // suit both XmlWebApplicationContext and ClassPathXmlApplicationContext
            AbstractRefreshableApplicationContext springContext = (AbstractRefreshableApplicationContext) applicationContext;
            if (!(springContext.getBeanFactory() instanceof DefaultListableBeanFactory)) {
                LOGGER.error("No suitable bean factory! The current factory class is {}",
                        springContext.getBeanFactory().getClass());
            }
            springFactory = (DefaultListableBeanFactory) springContext.getBeanFactory();
        } else if (applicationContext instanceof GenericApplicationContext) {
            // suit GenericApplicationContext
            GenericApplicationContext springContext = (GenericApplicationContext) applicationContext;
            springFactory = springContext.getDefaultListableBeanFactory();
        } else {
            LOGGER.error("No suitable application context! The current context class is {}",
                    applicationContext.getClass());
        }
    }

    /**
     * 将模板中定义的service,填充业务参数和扩展字段,添加到BeanFactory的definition中
     */
    private void loadTemplateBeanDefinitions(List<TemplateEntity> templateEntityList) {
        if (CollectionUtils.isEmpty(templateEntityList)) {
            LOGGER.warn("");
            return;
        }
        for (TemplateEntity templateEntity : templateEntityList) {
            if (templateEntity == null || CollectionUtils.isEmpty(templateEntity.getServiceList())) {
                continue;
            }
            Long templateId = templateEntity.getIndustryId();
            for (ServiceEntity serviceEntity : templateEntity.getServiceList()) {
                registerBeanDefinition(templateId.toString(), serviceEntity);
            }
        }
    }

    /**
     * 根据service信息,创建BeanDefinition
     *
     * @param templateId    模板ID
     * @param serviceEntity service信息
     */
    private void registerBeanDefinition(String templateId, ServiceEntity serviceEntity) {

        try {
            if (springFactory.containsBeanDefinition(serviceEntity.getImplName())) {
                //step1: 注入多个实例
                String beanKey = generateTemplateBeanName(templateId, serviceEntity.getServiceName());
                BeanDefinition beanDefinition = springFactory.getBeanDefinition(serviceEntity.getImplName());
                String className = beanDefinition.getBeanClassName();
                Class c = null;
                try {
                    c = Class.forName(className);
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                }

                BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.rootBeanDefinition(className);
                beanDefinitionBuilder.getBeanDefinition().setAttribute("id", beanKey);

                springFactory.registerBeanDefinition(
                        beanKey, beanDefinitionBuilder.getBeanDefinition());
                LOGGER.info("Register bean definition successfully. beanName:{}, implName:{}",
                        generateTemplateBeanName(templateId, serviceEntity.getServiceName()), serviceEntity.getImplName());

                //step2: 为实例自动化注入属性
                Object bean = springFactory.getBean(beanKey, c);
                injectParamVaules(bean, c, serviceEntity);
            }

        } catch (NoSuchBeanDefinitionException ex) {
            LOGGER.info("No bean definition in spring factory. implName:{}", serviceEntity.getImplName());
        } catch (BeanDefinitionStoreException ex) {
            LOGGER.info("Register bean definition wrong. beanName:{}, implName:{}",
                    generateTemplateBeanName(templateId, serviceEntity.getServiceName()), serviceEntity.getImplName());
        }
    }

    /**
     * 为bean实例注入业务参数和扩展字段
     *
     * @param bean
     * @param requiredType
     * @param serviceEntity
     * @param <T>
     */
    private <T> void injectParamVaules(Object bean, Class<T> requiredType, ServiceEntity serviceEntity) {

        if (requiredType.isAnnotationPresent(TemplateService.class)) {
            Field[] fields = requiredType.getDeclaredFields(); //获取类的所有属性
            for (Field field : fields) {
                // 注入业务参数
                if (field.isAnnotationPresent(TemplateBizParam.class)) {
                    field.setAccessible(true);
                    try {
                        if ((serviceEntity.getBizParamMap() != null) && (serviceEntity.getBizParamMap().containsKey(field.getName()))) {
                            field.set(bean, serviceEntity.getBizParamMap().get(field.getName()));
                            LOGGER.info("inject biz param value successfully, paramName = {}, value = {}", field.getName(), serviceEntity.getBizParamMap().get(field.getName()));
                        }
                    } catch (IllegalAccessException e) {
                        LOGGER.error("inject biz param failed. {}", e.getMessage());
                        e.printStackTrace();
                    }
                }
            }

            Class<AbstractService> superClass = getSuperClass(requiredType);
            if(superClass != null) {
                Field[] superFields = superClass.getDeclaredFields(); //获取类的所有属性
                for (Field field : superFields) {
                    // 注入扩展字段
                    if (field.isAnnotationPresent(TemplateExtendFields.class)) {
                        field.setAccessible(true);
                        try {
                            if(serviceEntity.getExtendFields() != null){
                                field.set(bean, serviceEntity.getExtendFields());
                                LOGGER.info("inject extend fields successfully, extendFields = {}", serviceEntity.getExtendFields());
                            }
                        } catch (IllegalAccessException e) {
                            LOGGER.error("inject extend fields failed. {}", e.getMessage());
                            e.printStackTrace();
                        }
                    }
                }
            }


        }
    }

    private Class<AbstractService> getSuperClass(Class clazz) {
        if (!AbstractService.class.isAssignableFrom(clazz)) {
            LOGGER.info("super class is null");
            return null;
        }
        Class<? extends AbstractService> superClass = clazz.getSuperclass();
        if (AbstractService.class != superClass) {
            superClass = getSuperClass(superClass);
        }
        return (Class<AbstractService>) superClass;
    }

    /***
     * 销毁模板bean
     */
    private void destroyTemplateBeans(List<TemplateEntity> changedTemplates) {

        if (CollectionUtils.isEmpty(changedTemplates)) {
            LOGGER.warn("");
            return;
        }
        for (TemplateEntity templateEntity : changedTemplates) {
            if (templateEntity == null || CollectionUtils.isEmpty(templateEntity.getServiceList())) {
                continue;
            }
            String templateId = templateEntity.getIndustryId().toString();
            for (ServiceEntity serviceEntity : templateEntity.getServiceList()) {

                if (springFactory.containsSingleton(generateTemplateBeanName(templateId, serviceEntity.getServiceName()))) {
//                    springFactory.destroySingleton(generateTemplateBeanName(templateId, serviceEntity.getServiceName()));  不需要显示的destroy方法,removeBeanDefinition中已调用此方法了
                    springFactory.removeBeanDefinition(generateTemplateBeanName(templateId, serviceEntity.getServiceName()));
                    LOGGER.info("destroy template beans successfully for beanName = {}", generateTemplateBeanName(templateId, serviceEntity.getServiceName()));
                }
            }
        }
    }


    /**
     * 从springFactory中获取bean
     *
     * @param name         bean名称
     * @param requiredType bean类型
     * @param <T>
     * @return
     * @throws BeansException
     */
    public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
        return springFactory.getBean(name, requiredType);
    }

    ;

    /**
     * 生成模板service实例名称
     *
     * @param templateId  模板ID
     * @param serviceName service名称
     * @return
     */
    public static final String generateTemplateBeanName(String templateId, String serviceName) {
        StringBuilder builder = new StringBuilder(serviceName);
        builder.append("_");
        builder.append(templateId);
        return builder.toString();
    }
}
分享到:
评论

相关推荐

    spring动态向容器中添加bean和删除指定bean.md

    spring动态向容器中添加bean和删除指定bean,不需要重启应用

    Spring Boot如何动态创建Bean示例代码

    主要给大家介绍了关于Spring Boot如何动态创建Bean的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。

    JSP 开发之Spring Boot 动态创建Bean

    JSP 开发之Spring Boot 动态创建Bean 1、通过注解@Import导入方式创建 a、新建MyImportBeanDefinitionRegistrar注册中心 Java代码  import org.springframework.beans.factory.support.BeanDefinitionRegistry;...

    Spring中如何动态注入Bean实例教程

    主要给大家介绍了关于Spring中如何动态注入Bean的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。

    如何在Spring中使用编码方式动态配置Bean详解

    主要给大家介绍了关于如何在Spring中使用编码方式动态配置Bean的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

    SSH笔记-通过实现FactoryBean接口来创建 Bean

    SSH笔记-通过实现FactoryBean接口来创建 Bean的demo,恩

    spring4示例代码

    spring-1 演示了使用setter方式及构造器方式创建bean,util:list标签创建集合,p标签简化配置 和依赖注入, 以及bean的autowire和继承与依赖,以及bean的作用域。 spring-2 演示了外部配置文件的引入(connection)...

    spring第三天.pdf

    2. 可以自主完成阅读Spring框架中Bean实例创建流程的源码 3. 可以自主完成阅读Spring框架中依赖注入流程的源码 4. 可以确定aop流程的源码阅读入口 5. 搞清楚aop相关的核心概念(通知、切面、切入点等) 6. 搞清楚...

    JAVA spring 系列案例50个和学习资料

    Spring系列第4篇:xml中bean定义详解(-)Spring系列第5篇:创建bean实例这些方式你们都知道?Spring系列第6篇:玩转bean scope,避免跳坑里!Spring系列第7篇:依赖注入之手动注入Spring系列第8篇:自动注入...

    吴天雄--Spring笔记.doc

    第一天内容:Spring框架简介(EJB、JMX、Spring核心功能、Spring模块详解、Spring重要概念(容器)、Spring容器初始化的整个流程、Spring后处理器),IOC详解,Spring环境搭建,Spring创建Bean的三种方式,scope属性...

    spring多数据源 创建 切换使用

    项目中我们经常会遇到多数据源的问题,尤其是数据同步或定时任务等项目更是如此。多数据源让人最头痛的,不是配置多个数据源,而是如何能灵活动态的切换数据源。 spring多数据源 动态 创建 切换使用

    Spring-Reference_zh_CN(Spring中文参考手册)

    12.2.2. 在Spring的application context中创建 SessionFactory 12.2.3. HibernateTemplate 12.2.4. 不使用回调的基于Spring的DAO实现 12.2.5. 基于Hibernate3的原生API实现DAO 12.2.6. 编程式的事务划分 12.2.7. ...

    spring+springmvc+mybatis的整合

    如果它们在SQL映射文件中定义过,则将它们动态定义为一个Spring Bean, 这样,我们在Service中就可以直接注入映射接口的bean 意思就是可以直接ref="dao类名",给你自动注册好了 2.7 写mybatis的配置文件,一个...

    spring.doc

    3.3 Spring容器内部对象的创建 12 Spring容器内部对象创建拓展: 12 3.3.1使用类构造器实例化(默认无参数) 14 3.3.2使用静态工厂方法实例化(简单工厂模式) 14 3.3.3初始化(创建)bean时机 15 Lazy-init初始化bean的...

    Spring 2.0 开发参考手册

    12.2.2. 在Spring的application context中创建 SessionFactory 12.2.3. HibernateTemplate 12.2.4. 不使用回调的基于Spring的DAO实现 12.2.5. 基于Hibernate3的原生API实现DAO 12.2.6. 编程式的事务划分 12.2.7...

    Spring中文帮助文档

    12.2.2. 在Spring容器中创建 SessionFactory 12.2.3. The HibernateTemplate 12.2.4. 不使用回调的基于Spring的DAO实现 12.2.5. 基于Hibernate3的原生API实现DAO 12.2.6. 编程式的事务划分 12.2.7. 声明式的...

    workshop-spring-4.0-to-4.2:Spring 4新功能研讨会

    工作坊-从Spring 4.0到4.2 该研讨会实现了从4.0到4.2发行版的大多数Spring Framework功能的示例。 如何使用 ? 运行Spring Boot Application应用程序 ... 可用于动态创建bean(迭代) 可以在运行时加载 泛型类型作

    Spring API

    12.2.2. 在Spring容器中创建 SessionFactory 12.2.3. The HibernateTemplate 12.2.4. 不使用回调的基于Spring的DAO实现 12.2.5. 基于Hibernate3的原生API实现DAO 12.2.6. 编程式的事务划分 12.2.7. 声明式的...

    spring chm文档

    12.2.2. 在Spring的application context中创建 SessionFactory 12.2.3. HibernateTemplate 12.2.4. 不使用回调的基于Spring的DAO实现 12.2.5. 基于Hibernate3的原生API实现DAO 12.2.6. 编程式的事务划分 12.2.7...

Global site tag (gtag.js) - Google Analytics