Dozer的学习

article/2025/9/9 8:03:30

Dozer的学习

此教程基于黑马程序员Java品达通用权限项目,哔哩哔哩链接:https://www.bilibili.com/video/BV1tw411f79E?p=44

1.dozer介绍

Dozer是Java Bean到Java Bean映射器,它以递归方式将数据从一个对象复制到另一个对象。 dozer是用来对两个对象之间属性转换的工具,有了这个工具之后,我们将一个对象的所有属性值转给另一个对象时,就不需要再去写重复的调用set和get方法了。

dozer其实是对我们熟知的beanutils的封装。

dozer的maven坐标:

<dependency><groupId>com.github.dozermapper</groupId><artifactId>dozer-core</artifactId><version>6.5.0</version>
</dependency>

为了简化使用方式,dozer还提供了starter,其maven坐标为:

<dependency><groupId>com.github.dozermapper</groupId><artifactId>dozer-spring-boot-starter</artifactId><version>6.5.0</version>
</dependency>

2.dozer入门案例

第一步:创建maven工程dozer_demo并配置pom.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.2.2.RELEASE</version><relativePath/></parent><groupId>cn.itcast</groupId><artifactId>dozer_demo</artifactId><version>1.0-SNAPSHOT</version><dependencies><!-- dozer --><dependency><groupId>com.github.dozermapper</groupId><artifactId>dozer-spring-boot-starter</artifactId><version>6.5.0</version></dependency><!-- 单元测试 --><dependency><groupId>junit</groupId><artifactId>junit</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId></dependency><!-- lombok --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency></dependencies></project>

第二步:创建UserDTO和UserEntity ,此处我们故意对某些属性、数据类型设置不一致,如在UserDTO中的属性UserId和UserEntity 中的id,UserDTO的birthday的数据类型为String,而UserEntity的birthday数据类型为Date

DTO一般表示数据传输对象,Entity 一般与数据库表进行映射

package com.itheima.dto;import lombok.Data;@Data
public class UserDTO {private String userId;private String userName;private int userAge;private String address;private String birthday;
}
package com.itheima.entity;import lombok.Data;
import java.util.Date;@Data
public class UserEntity {private String id;private String name;private int age;private String address;private Date birthday;
}

第三步:在resources/dozer/目录下创建dozer的全局配置文件global.dozer.xml

<?xml version="1.0" encoding="UTF-8"?>
<mappings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns="http://dozermapper.github.io/schema/bean-mapping"xsi:schemaLocation="http://dozermapper.github.io/schema/bean-mapping http://dozermapper.github.io/schema/bean-mapping.xsd"><!--全局配置:<date-format>表示日期格式--><configuration><date-format>yyyy-MM-dd</date-format></configuration>
</mappings>

注:全局配置文件名称可以任意

第四步:在resources/dozer/目录下创建dozer的映射文件biz.dozer.xml ,用于映射UserDTO和UserEntity之间的关系

<?xml version="1.0" encoding="UTF-8"?>
<mappings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns="http://dozermapper.github.io/schema/bean-mapping"xsi:schemaLocation="http://dozermapper.github.io/schema/bean-mappinghttp://dozermapper.github.io/schema/bean-mapping.xsd"><!--描述两个类中属性的对应关系,对于两个类中同名的属性可以不映射--><mapping date-format="yyyy-MM-dd"><class-a>com.itheima.entity.UserEntity</class-a><class-b>com.itheima.dto.UserDTO</class-b><!-- field:属性对应,这里表示 UserEntity的id属性与 UserDTO的userId进行对应如果是完全相同的属性就可以不用进行配置--><field><a>id</a><b>userId</b></field><field><a>name</a><b>userName</b></field><field><a>age</a><b>userAge</b></field></mapping><!--可以使用map-id指定映射的标识,在程序中通过此标识来确定使用当前这个映射关系--><mapping date-format="yyyy-MM-dd" map-id="user"><class-a>com.itheima.entity.UserEntity</class-a><class-b>com.itheima.dto.UserDTO</class-b><field><a>id</a><b>userId</b></field><field><a>name</a><b>userName</b></field><field><a>age</a><b>userAge</b></field></mapping>
</mappings>

注:映射文件名称可以任意

第五步:编写application.yml文件

dozer:mappingFiles: # mappingFiles 为一个数组- classpath:dozer/global.dozer.xml # dozer全局配置文件- classpath:dozer/biz.dozer.xml  # UserDTO与UserEntity的映射文件

第六步:编写启动类DozerApp

package com.itheima;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class DozerApp {public static void main(String[] args) {SpringApplication.run(DozerApp.class,args);}
}

第七步:编写单元测试DozerTest

package cn.itcast.test;import com.github.dozermapper.core.DozerBeanMapper;
import com.github.dozermapper.core.DozerBeanMapperBuilder;
import com.github.dozermapper.core.Mapper;
import com.github.dozermapper.core.metadata.MappingMetadata;
import com.itheima.DozerApp;
import com.itheima.dto.UserDTO;
import com.itheima.entity.UserEntity;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;@RunWith(SpringRunner.class)
@SpringBootTest(classes = DozerApp.class) // 指定启动类
public class DozerTest {// 注入mapper对象,因为我们在pom文件中已经引入了dozer-spring-boot-starter依赖,它已经帮我们完成了自动配置// 使用mapper对象可以完成两个对象之间属性的复制@Autowiredprivate Mapper mapper;@Testpublic void testDozer1(){UserDTO userDTO = new UserDTO();userDTO.setUserId("100");userDTO.setUserName("itcast");userDTO.setUserAge(20);userDTO.setAddress("bj");// 我们在dozer的全局配置文件中定义了日期的格式为yyyy-MM-dduserDTO.setBirthday("2010-11-20");// 将UserDTO的属性对应的复制到UserEntity对象上UserEntity user = mapper.map(userDTO, UserEntity.class);System.out.println(user);}
}

我们发现dozer帮我们把UserDTO的属性对应的复制到了UserEntity对象上

image-20220115170446967

继续编写测试,

	@Testpublic void testDozer2(){UserDTO userDTO = new UserDTO();userDTO.setUserId("100");userDTO.setUserName("itcast");userDTO.setUserAge(20);userDTO.setAddress("bj");userDTO.setBirthday("2010-11-20");UserEntity user = new UserEntity();user.setId("200");System.out.println(user);// 调用map方法进行复制后,user对象的值会被覆盖mapper.map(userDTO, user);System.out.println(user);}

我们发现,调用map方法进行复制后,user对象的值会被覆盖

image-20220115170702282

我们想要使用在biz.dozer映射文件中具体的某个map-id的配置,如此处我们使用map-id为user的映射配置

image-20220115171026300

我们在map方法中添加第三个参数指定map-id即可

// 使用我们映射文件中的map—id为user的配置
mapper.map(userDTO, user, "user");

3.定制starter

我们在实际的项目中可以将dozer的配置定制为一个starter,之后在我们的项目中直接引入即可。

1.首先我们新建一个maven项目,并命名为pd-tools-dozer,引入dozer依赖,具体pom.xml文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.2.2.RELEASE</version><relativePath/></parent><groupId>cn.itcast</groupId><artifactId>pd-tools-dozer</artifactId><version>1.0-SNAPSHOT</version><dependencies><!-- dozer --><dependency><groupId>com.github.dozermapper</groupId><artifactId>dozer-spring-boot-starter</artifactId><version>6.5.0</version></dependency></dependencies></project>

2.新建util包并在其包下新建一个工具类DozerUtils,使用Mapper对象进行操作,具体代码如下:

DozerUtils.java

package com.itheima.util;import com.github.dozermapper.core.Mapper;import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;/*** DozerUtils 工具类**/
public class DozerUtils {private Mapper mapper;public DozerUtils(Mapper mapper) {this.mapper = mapper;}public Mapper getMapper() {return this.mapper;}/*** Constructs new instance of destinationClass and performs mapping between from source** @param source* @param destinationClass* @param <T>* @return*/public <T> T map(Object source, Class<T> destinationClass) {if (source == null) {return null;}return mapper.map(source, destinationClass);}public <T> T map2(Object source, Class<T> destinationClass) {if (source == null) {try {return destinationClass.newInstance();} catch (Exception e) {}}return mapper.map(source, destinationClass);}/*** Performs mapping between source and destination objects** @param source* @param destination*/public void map(Object source, Object destination) {if (source == null) {return;}mapper.map(source, destination);}/*** Constructs new instance of destinationClass and performs mapping between from source** @param source* @param destinationClass* @param mapId* @param <T>* @return*/public <T> T map(Object source, Class<T> destinationClass, String mapId) {if (source == null) {return null;}return mapper.map(source, destinationClass, mapId);}/*** Performs mapping between source and destination objects** @param source* @param destination* @param mapId*/public void map(Object source, Object destination, String mapId) {if (source == null) {return;}mapper.map(source, destination, mapId);}/*** 将集合转成集合* List<A> -->  List<B>** @param sourceList       源集合* @param destinationClass 待转类型* @param <T>* @return*/public <T, E> List<T> mapList(Collection<E> sourceList, Class<T> destinationClass) {return mapPage(sourceList, destinationClass);}public <T, E> List<T> mapPage(Collection<E> sourceList, Class<T> destinationClass) {if (sourceList == null || sourceList.isEmpty() || destinationClass == null) {return Collections.emptyList();}List<T> destinationList = sourceList.stream().filter(item -> item != null).map((sourceObject) -> mapper.map(sourceObject, destinationClass)).collect(Collectors.toList());return destinationList;}public <T, E> Set<T> mapSet(Collection<E> sourceList, Class<T> destinationClass) {if (sourceList == null || sourceList.isEmpty() || destinationClass == null) {return Collections.emptySet();}return sourceList.stream().map((sourceObject) -> mapper.map(sourceObject, destinationClass)).collect(Collectors.toSet());}
}

3.新建config包并在其包下新建DozerAutoConfiguration配置类,在配置类DozerAutoConfiguration中完成DozerUtils对象的创建,这样其他的程序如果需要使用dozer进行对象转换,只需要引入这个模块的maven坐标并且提供对应的映射文件就可以在程序中直接注入DozerUtils对象进行操作了。具体代码如下:

DozerAutoConfiguration.java

package com.itheima.config;import com.github.dozermapper.core.Mapper;
import com.itheima.util.DozerUtils;
import org.springframework.context.annotation.Bean;/*** Dozer spring auto configuration.* <p>* ConditionalOnClass:该注解的参数对应的类必须存在,否则不解析该注解修饰的配置类;* ConditionalOnMissingBean:该注解表示,如果存在它修饰的类的bean,则不需要再创建这个bean;* <p>* http://dozer.sourceforge.net/documentation/usage.html* http://www.jianshu.com/p/bf8f0e8aee23**/
public class DozerAutoConfiguration {@Beanpublic DozerUtils getDozerUtils(Mapper mapper) {DozerUtils dozerUtils = new DozerUtils(mapper);return dozerUtils;}
}

4.在resources目录下新建dozer全局配置文件 global.dozer.xml

global.dozer.xml

<?xml version="1.0" encoding="UTF-8"?>
<mappings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns="http://dozermapper.github.io/schema/bean-mapping"xsi:schemaLocation="http://dozermapper.github.io/schema/bean-mapping http://dozermapper.github.io/schema/bean-mapping.xsd"><!--@see: http://www.jianshu.com/p/bf8f0e8aee23@see: http://blog.csdn.net/whhahyy/article/details/48594657全局配置:<date-format>表示日期格式<stop-on-errors>错误处理开关<wildcard>通配符<trim-strings>裁剪字符串开关--><configuration><date-format>yyyy-MM-dd HH:mm:ss</date-format></configuration>
</mappings>

5.按照Spring Boot starter的规范(没有starter基础的可以去看我的starter博客,点击前往)编写/resources/META-INF/spring.factories文件,内容如下:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\com.itheima.config.DozerAutoConfiguration

注:如果有多个配置,以英文逗号分隔即可

6.之后对该maven项目进行打包的操作,

image-20220115174407743

4.使用starter

第一步:创建maven工程myDozerApp并配置pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.2.2.RELEASE</version><relativePath/></parent><groupId>com.itheima</groupId><artifactId>myDozerApp</artifactId><version>1.0-SNAPSHOT</version><dependencies><!--引入我们自己定义的dozer基础模块--><dependency><groupId>com.itheima</groupId><artifactId>pd-tools-dozer</artifactId><version>1.0-SNAPSHOT</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency></dependencies>
</project>

注意:为防止我们自定义的starter识别不到,我们需要更新一下maven仓库,

image-20220114225646904

第二步:创建UserEntity和UserDTO

package com.itheima.entity;import lombok.Data;@Data
public class UserEntity {private Integer id;private String name;private int age;
}
package com.itheima.dto;import lombok.Data;@Data
public class UserDTO {private Integer id;private String name;private int age;
}

第三步:创建UserController

package com.itheima.controller;import com.itheima.dto.UserDTO;
import com.itheima.entity.UserEntity;
import com.itheima.util.DozerUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/user")
public class UserController {@Autowiredprivate DozerUtils dozerUtils; //在pd-tools-dozer中已经完成了自动配置,可以直接注入@GetMapping("/mapper")public UserEntity mapper(){UserDTO userDTO = new UserDTO();userDTO.setId(10);userDTO.setName("itcast");userDTO.setAge(20);UserEntity userEntity = dozerUtils.map(userDTO, UserEntity.class);return userEntity;}
}

第四步:创建application.yml

server:port: 8080

第五步:创建启动类

package com.itheima;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class MyDozerApplication {public static void main(String[] args) {SpringApplication.run(MyDozerApplication.class,args);}
}

启动项目,访问地址:http://localhost:8080/user/mapper ,我们发现dozer已经帮我们把UserDTO转换为了UserEntity

image-20200311132120704

注意:由于当前我们创建的UserEntity和UserDTO中的属性完全一致,所以并没有提供映射文件,如果这两个类中的属性存在不一致的情况,需要创建映射文件进行映射,并且还需要在application.yml中配置映射文件的位置,例如:

dozer:mappingFiles:- classpath:dozer/biz.dozer.xml  #指定dozer的映射文件位置

喜欢请关注我

至此,我们的Dozer的学习就讲解完毕了。喜欢我的话可以关注我的微信公众号 我爱学习呀嘻嘻 ,不定期分享各类资源哦。
在这里插入图片描述


http://chatgpt.dhexx.cn/article/j0WaOUgg.shtml

相关文章

SpringBoot Dozer

文章目录 Dozerspringboot 配置 Dozer演示Dozer工具接口和实现类全面测试项目实战演示 Dozer Dozer是什么? Dozer是一个JavaBean映射工具库。 它支持简单的属性映射&#xff0c;复杂类型映射&#xff0c;双向映射&#xff0c;隐式显式的映射&#xff0c;以及递归映射。 它支…

Dozer的使用(整合springboot)

dozer是实体类与实体类之间转换的工具&#xff0c;下面是简单操作配置 引入依赖&#xff1a; <!--dozer 实体类转换工具--><dependency><groupId>net.sf.dozer</groupId><artifactId>dozer-spring</artifactId><version>5.5.1<…

【JAVA】Dozer 介绍及快速入门教程

文章目录 概述使用安装入门XML 映射注解映射SpringBoot 集成 结语 概述 Dozer 是什么? Dozer 是 Java Bean 到 Java Bean 的映射器&#xff0c;他以递归的方式将数据从一个对象复制到另一个对象。 它支持简单的属性映射&#xff0c;复杂类型映射&#xff0c;双向映射&#…

1.Dubbo教程

转自&#xff1a;https://blog.csdn.net/hellozpc/article/details/78575773 2. 什么是dubbo 2.1. 简介 DUBBO是一个分布式服务框架&#xff0c;致力于提供高性能和透明化的RPC远程服务调用方案&#xff0c;是阿里巴巴SOA服务化治理方案的核心框架&#xff0c;每天为2,000个服务…

黑马程序员Dubbo快速入门,Java分布式框架dubbo教程

分布式系统中的相关概念 &#xff08;一&#xff09;互联网项目架构目标-特点 &#xff08;二&#xff09;互联网项目架构目标-目标 &#xff08;三&#xff09;集群和分布式 &#xff08;四&#xff09;架构演进 Dubbo概述 &#xff08;一&#xff09;dubbo概述 1、dub…

Dubbo快速入门教程

Dubbo入门教程 1 、Dubbo概述 DUbbo架构 2、Dubbo快速入门 Zookeeper 安装传统的模块化开发Duboo入门小案例 修改Service模块代码修改WEB模块代码增加公共的接口模块 3、Dubbo高级特性 dubbo-admin管理平台 dubbo-adminm安装 一、dubbo-admin安装二、dubbo-admin简单使用 序…

dubbo教程总结(springboot+dubbo)

概述 Apache Dubbo 是一款微服务开发框架&#xff0c;它提供了 RPC通信 与 微服务治理 两大关键能力。这意味着&#xff0c;使用 Dubbo 开发的微服务&#xff0c;将具备相互之间的远程发现与通信能力&#xff0c; 同时利用 Dubbo 提供的丰富服务治理能力&#xff0c;可以实现诸…

Dubbo入门详细教程

什么是Dubbo&#xff1f; Dubbo 是阿里开源的远程服务调用(RPC)的分布式框架&#xff0c;提供了 SOA 服务治理方案;它的架构主要有五个角色/核心组件&#xff0c;分为是 Container(容器)、Provider(服务的提供方)、Registry(注册中心)、Consumer(服务的消费方)、Monitor(监控中…

dubbo 教程

&#xfeff;&#xfeff; 先给出阿里巴巴dubbo的主页&#xff1a;http://code.alibabatech.com/wiki/display/dubbo/Home-zh 自己的demo下载地址&#xff1a;http://download.csdn.net/detail/u012049463/6763315 1. Dubbo是什么&#xff1f; Dubbo是一个分布式服务框架&…

dubbo使用教程(可直接应用于企业开发)

本dubbo使用教程基于zookeeper-3.4.9搭建&#xff0c;包含服务提供者DubboProvider、和消费者DubboConsumer&#xff0c;可直接在Tomcat上运行。DubboProvider对外开放2个接口&#xff0c;DubboConsumer调用DubboProvider&#xff0c;并对外暴露HTTP服务。DubboProvider还提供了…

Dubbo快速入门

前言&#xff1a;本文需要建立在博主的环境之上来进行&#xff0c;大家也可以用自己的环境测试一下看能不能行得通&#xff0c;如果可以的话请在下方评论&#xff0c;让更多的人知道 Jdk&#xff1a;11 Springboot版本&#xff1a;2.6.6 Dubbo版本&#xff1a;0.2.0&#xf…

dubbo最全的使用教程

dubbo是阿里一款高性能&#xff0c;轻量级的rpc框架&#xff0c;有两大核心功能&#xff1a;远程服务调用和服务治理。本文主要介绍dubbo的运用。 一&#xff0c;安装注册中心zookeeper 1&#xff0c;为什么需要注册中心&#xff0c;不要能不能远程服务调用 答&#xff1a;可以…

VS2017安装教程(详细版)

1.首先下载好安装包 百度网盘下载链接 链接&#xff1a;https://pan.baidu.com/s/1HW8hrLMazRsBkPvkDHkD1Q?pwdz4jg 提取码&#xff1a;z4jg 2.下载到桌面以管理员身份运行 点击继续 3.进入后更改安装位置&#xff0c;选择安装路径&#xff0c;千万不要安装到C盘 4.改完后…

vs2017秘钥

vs2017 企业版秘钥&#xff1a;NJVYC-BMHX2-G77MM-4XJMR-6Q8QF 专业版秘钥&#xff1a;KBJFW-NXHK6-W4WJM-CRMQB-G3CDH 欢迎使用Markdown编辑器 你好&#xff01; 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章…

自定义 Tabhost 样式

经过了一天的折腾, 在网上也找了不少源码&#xff0c; 但是效果都不是很好&#xff0c;非常长&#xff0c; 最后自己终于写出了一个代码不是很多的Tabhost。 先上图(背景是随便弄的, 所以不怎么样) 首先&#xff0c; 我们要先写一个主xml main.xml 每一个LinearLayout代表…

tabHost 使用方法

近日 学习TabHost的使用 再网上搜不少文章 觉得这篇写的挺好 &#xff01; 出处 &#xff1a;http://www.blogjava.net/freeman1984/archive/2010/10/29/302803.html 查看tabhost的源代码&#xff0c;主要实例变量有&#xff1a; private TabWidget mTabWidget; priv…

android Tabhost控件的使用

Tabhost用来实现如图的效果&#xff1a; 上图的首页、自选、警报是由Tabhost控件来实现的&#xff0c;Tabhost控件中的每个tab其实都是一个Activity&#xff0c;也就是说我创建一个Tabhost&#xff0c;在tabhost中添加tab页就可以实现。 实现方式&#xff1a;1、创建布局文件 …

TabHost详解0

一、TabHost是一个选项卡容器&#xff0c;通过标签页将多个Activity整合到一起。 TabHost的三要素为&#xff1a;TabWidget、FrameLayout、List<TabSpec>。 其主要的使用方式有两种&#xff1a; 1.继承TabActivity&#xff0c;结合对应的xml配置文件导入tab选项内容体 …

TabHost

TabHost的实现有两种方式&#xff0c;第一种继承TabActivity&#xff0c;从TabActivity中用getTabHost()方法获取TabHost。各个Tab中的内容在布局文件中定义就行了。 mainActivity.xml private TabHost myTabHost;Overridepublic void onCreate(Bundle savedInstanceState) {su…

Android初级控件TabHost

TabHost我们都知道是用来实现导航栏布局来切换页面的&#xff0c;这个也是元老级的控件了&#xff0c;现在逐渐被TabLayout,BottomNavigationBar,使用RadioButton自定义。。。等等给取代了。TabHost有个好处就是它添加的是Activity而不像上面那些全部使用Fragment来显示内容。 …