ioc的练习
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--实验1:通过IOC容器创建对象,并为属性赋值★ -->
<!-- 注册一个Person对象,Spring会自动创建这个Person对象 -->
<!--
一个Bean标签可以注册一个组件(对象、类)
class:写要注册的组件的全类名
id:这个对象的唯一标示;
-->
<bean id="person01" class="com.atguigu.bean.Person">
<!--使用property标签为Person对象的属性赋值
name="lastName":指定属性名
value="张三":为这个属性赋值
-->
<property name="lastName" value="张三"></property>
<property name="age" value="18"></property>
<property name="email" value="zhangsan@atguigu.com"></property>
<property name="gender" value="男"></property>
</bean>
<bean id="person02" class="com.atguigu.bean.Person">
<property name="lastName" value="小花"></property>
</bean>
<bean id="person03" class="com.atguigu.bean.Person">
<!-- 调用有参构造器进行创建对象并赋值;掌握 -->
<!-- public Person(String lastName, Integer age, String gender, String email) -->
<constructor-arg name="lastName" value="小明"></constructor-arg>
<constructor-arg name="email" value="xiaoming@atguigu.com"></constructor-arg>
<constructor-arg name="gender" value="男"></constructor-arg>
<constructor-arg name="age" value="18"></constructor-arg>
</bean>
<!-- 实验3:
通过构造器为bean的属性赋值(index,type属性介绍)
通过p名称空间为bean赋值-->
<!--可以省略name属性,严格按照构造器参数的位置 -->
<bean id="person04" class="com.atguigu.bean.Person">
<constructor-arg value="小花"></constructor-arg>
<constructor-arg value="18"></constructor-arg>
<!-- index="3":为参数指定索引,从0开始 -->
<constructor-arg value="xiaohua@atguigu.com" index="3"></constructor-arg>
<constructor-arg value="男" index="2"></constructor-arg>
</bean>
<!--public Person(String lastName, Integer age, String gender) -->
<!--public Person(String lastName, String email, String gender) -->
<!-- 重载的情况下type可以指定参数的类型 -->
<bean id="person05" class="com.atguigu.bean.Person">
<constructor-arg value="小丽"></constructor-arg>
<constructor-arg value="10" index="1" type="java.lang.Integer"></constructor-arg>
<constructor-arg value="男"></constructor-arg>
</bean>
<!-- 通过p名称空间为bean赋值;导入p名称空间 -->
<!--名称空间:在xml中名称空间是用来防止标签重复的 -->
<!--使用p命名空间可以用bean 元素的属性代替<property/>元素
<!--1)、导入p名称空间 2)、写带前缀的标签/属性 -->
<!--
<book>
<b:name>西游记</b:name>
<price>19.98</price>
<author>
<a:name>吴承恩</a:name>
<gender>男</gender>
</author>
</book>
带前缀的标签<c:forEach> <jsp:forward>
-->
<bean id="person06" class="com.atguigu.bean.Person"
p:age="18" p:email="xiaoming@atguigu.com"
p:lastName="哈哈" p:gender="男">
</bean>
</beans>
=========================================================================================
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">
<!-- 实验4:正确的为各种属性赋值 测试使用null值 、 引用类型赋值(引用其他bean、引用内部bean) 集合类型赋值(List、Map、Properties)、
util名称空间创建集合类型的bean 级联属性赋值 -->
<bean id="car01" class="com.atguigu.bean.Car">
<property name="carName" value="宝马"></property>
<property name="color" value="绿色"></property>
<property name="price" value="30000"></property>
</bean>
<bean id="person01" class="com.atguigu.bean.Person">
<!-- lastName="null" -->
<property name="lastName">
<!-- 进行复杂的赋值 -->
<null />
</property>
<!-- ref:代表引用外面的一个值 ;引用其他bean car = ioc.getBean("car01") -->
<!-- <property name="car" ref="car01"></property> -->
<property name="car">
<!--对象我们可以使用bean标签创建 car = new Car(); 引用内部bean;不能被获取到,只能内部使用 -->
<bean class="com.atguigu.bean.Car">
<property name="carName" value="自行车"></property>
</bean>
</property>
</bean>
<bean id="book01" class="com.atguigu.bean.Book">
<property name="bookName" value="东游记"></property>
</bean>
<bean id="person02" class="com.atguigu.bean.Person">
<!-- 如何为list类型赋值 -->
<property name="books">
<!-- books = new ArrayList<Book>(); -->
<list>
<!-- list标签体中添加每一个元素 -->
<bean class="com.atguigu.bean.Book" p:bookName="西游记"></bean>
<!-- 引用外部一个元素 -->
<ref bean="book01" />
</list>
</property>
<!-- Map<String, Object> maps; -->
<property name="maps">
<!-- maps = new LinkedHashMap<>(); -->
<map>
<!-- 一个entry代表一个键值对 -->
<entry key="key01" value="张三"></entry>
<entry key="key02" value="18"></entry>
<entry key="key03" value-ref="book01"></entry>
<entry key="key04">
<bean class="com.atguigu.bean.Car">
<property name="carName" value="宝马"></property>
</bean>
</entry>
<entry key="key05">
<value>李四</value>
</entry>
<!-- <entry key="key05"> <map></map> </entry> -->
</map>
</property>
<!-- private Properties properties; -->
<property name="properties">
<!-- properties = new Properties();所有的k=v都是string -->
<props>
<!-- k=v都是string;值直接写在标签体中 -->
<prop key="username">root</prop>
<prop key="password">123456</prop>
</props>
</property>
</bean>
<!-- util名称空间创建集合类型的bean;方便别人引用 -->
<bean id="person03" class="com.atguigu.bean.Person">
<!-- <property name="maps" ></property> -->
<property name="maps" ref="myMap"></property>
</bean>
<!-- 相当于new LinkedHashMap<>() -->
<util:map id="myMap">
<!-- 添加元素 -->
<entry key="key01" value="张三"></entry>
<entry key="key02" value="18"></entry>
<entry key="key03" value-ref="book01"></entry>
<entry key="key04">
<bean class="com.atguigu.bean.Car">
<property name="carName" value="宝马"></property>
</bean>
</entry>
<entry key="key05">
<value>李四</value>
</entry>
</util:map>
<!-- 解释:4个元素
[[],Person,12,{}]
-->
<util:list id="myList">
<list></list>
<bean class="com.atguigu.bean.Person"></bean>
<value>12</value>
<ref bean="myMap"/>
</util:list>
<!-- 级联属性赋值: 级联属性:属性的属性-->
<bean id="person04" class="com.atguigu.bean.Person">
<!--为car赋值的时候。改变car的价格 -->
<property name="car" ref="car01"></property>
<!-- -->
<property name="car.price" value="900000"></property>
</bean>
<!--
实验6:通过继承实现bean配置信息的重用
实验7:通过abstract属性创建一个模板bean
实验8:bean之间的依赖
实验9:测试bean的作用域,分别创建单实例和多实例的bean★
-->
<!-- abstract="true":这个bean的配置是一个抽象的,不能获取他的实例,只能被别人用来继承 -->
<bean id="person05" class="com.atguigu.bean.Person" abstract="true">
<property name="lastName" value="张三"></property>
<property name="age" value="18"></property>
<property name="gender" value="男"></property>
<property name="email" value="zhangsan@atguigu.com"></property>
</bean>
<!--parent:指定当前bean的配置信息继承于哪个 -->
<bean id="person06" class="com.atguigu.bean.Person" parent="person05">
<property name="lastName" value="李四"></property>
</bean>
</beans>
=============================================================================================
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 原来是按照配置的顺序创建bean -->
<!-- 改变bean的创建顺序 -->
<!--实验8:bean之间的依赖(只是改变创建顺序) -->
<bean id="car" class="com.atguigu.bean.Car" depends-on="person"></bean>
<bean id="person" class="com.atguigu.bean.Person"></bean>
<!-- 实验9:测试bean的作用域,分别创建单实例和多实例的bean★
bean的作用域:指定bean是否单实例,xxx;默认:单实例的
prototype:多实例的;
1)、容器启动默认不会去创建多实例bean
2)、获取的时候创建这个bean
3)、每次获取都会创建一个新的对象
singleton:单实例的;默认的;
1)、在容器启动完成之前就已经创建好对象,保存在容器中了。
2)、任何获取都是获取之前创建好的那个对象;
request:在web环境下,同一次请求创建一个Bean实例(没用)
session:在web环境下,同一次会话创建一个Bean实例(没用)
-->
<bean id="book" class="com.atguigu.bean.Book" scope="prototype"></bean>
<!--实验5:配置通过静态工厂方法创建的bean、实例工厂方法创建的bean、FactoryBean★ -->
<!-- bean的创建默认就是框架利用反射new出来的bean实例 -->
<!-- 工厂模式;工厂帮我们创建对象;有一个专门帮我们创建对象的类,这个类就是工厂
AirPlane ap = AirPlaneFactory.getAirPlane(String jzName);
静态工厂:工厂本身不用创建对象;通过静态方法调用,对象 = 工厂类.工厂方法名();
实例工厂:工厂本身需要创建对象;
工厂类 工厂对象 = new 工厂类();
工厂对象.getAirPlane("张三");
-->
<!-- 1、静态工厂(不需要创建工厂本身)factory-method="getAirPlane":
指定哪个方法是工厂方法
class:指定静态工厂全类名
factory-method:指定工厂方法
constructor-arg:可以为方法传参
-->
<bean id="airPlane01" class="com.atguigu.factory.AirPlaneStaticFactory"
factory-method="getAirPlane">
<!-- 可以为方法指定参数 -->
<constructor-arg value="李四"></constructor-arg>
</bean>
<!--2、实例工厂使用
factory-method;指定这个实例工厂中哪个方法是工厂方法;
-->
<bean id="airPlaneInstanceFactory"
class="com.atguigu.factory.AirPlaneInstanceFactory"></bean>
<!-- factory-bean:指定当前对象创建使用哪个工厂
1、先配置出实例工厂对象
2、配置我们要创建的AirPlane使用哪个工厂创建
1)、factory-bean:指定使用哪个工厂实例
2)、factory-method:使用哪个工厂方法
-->
<bean id="airPlane02" class="com.atguigu.bean.AirPlane"
factory-bean="airPlaneInstanceFactory"
factory-method="getAirPlane">
<constructor-arg value="王五"></constructor-arg>
</bean>
<!-- FactoryBean★(是Spring规定的一个接口);
只要是这个接口的实现类,Spring都认为是一个工厂;
1、ioc容器启动的时候不会创建实例
2、FactoryBean;获取的时候的才创建对象
-->
<bean id="myFactoryBeanImple"
class="com.atguigu.factory.MyFactoryBeanImple"></bean>
</beans>
================================================================================================
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 实验10:创建带有生命周期方法的bean
生命周期:bean的创建到销毁;
ioc容器中注册的bean;
1)、单例bean,容器启动的时候就会创建好,容器关闭也会销毁创建的bean
2)、多实例bean,获取的时候才创建;
我们可以为bean自定义一些生命周期方法;spring在创建或者销毁的时候就会调用指定的方法;
自定义初始化方法和销毁方法; The method must have no arguments,but may throw any exception
-->
<bean id="book01" class="com.atguigu.bean.Book"
destroy-method="myDestory" init-method="myInit" ></bean>
<!--实验11:测试bean的后置处理器:BeanPostProcessor
Spring有一个接口:后置处理器:可以在bean的初始化前/后调用此方法;
-->
<bean id="beanPostProcessor" class="com.atguigu.bean.MyBeanPostProcessor"></bean>
<bean id="car01" class="com.atguigu.bean.Car"></bean>
</beans>
================================================================================================
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<!--实验12:引用外部属性文件★依赖context名称空间 -->
<!-- 数据库连接池作为单实例是最好的;一个项目就一个连接池,连接池里面管理很多连接。连接是直接从连接池中拿 -->
<!-- 可以让Spring帮我们创建连接池对象,(管理连接池) -->
<!--加载外部配置文件 固定写法classpath:,表示引用类路径下的一个资源-->
<context:property-placeholder location="classpath:dbconfig.properties"/>
<!-- username是Spring的key中的一个关键字;
为了防止配置文件中的key和spring自己的关键字冲突。我们可以给配置文件中的key加上一个前缀 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="user" value="${jdbc.username}"></property>
<!-- ${key}动态取出配置文件中某个key对应的值 -->
<property name="password" value="${jdbc.password}"></property>
<property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
<property name="driverClass" value="${jdbc.driverClass}"></property>
</bean>
<bean id="car01" class="com.atguigu.bean.Car">
<property name="carName" value="${username}"></property>
</bean>
</beans>
================================================================================================
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--实验13:基于XML的自动装配 -->
<bean id="car" class="com.atguigu.bean.Car">
<property name="carName" value="宝马"></property>
<property name="color" value="白色"></property>
</bean><!-- -->
<!-- <bean id="car02" class="com.atguigu.bean.Car">
<property name="carName" value="BWM"></property>
<property name="color" value="白色"></property>
</bean> --> <!-- -->
<!-- 为Person里面的自定义类型的属性赋值
property:手动赋值
自动赋值(自动装配):
自动装配:(仅限于对自定义类型的属性有效)
autowire="default/no":不自动装配;不自动为car属性赋值
//按照某种规则自动装配
autowire="byName":按照名字;
private Car car;
1)、以属性名(car)作为id去容器中找到这个组件,给他赋值;如果找不到就装配null;
car = ioc.getBean("car");
autowire="byType":
private Car car;
1)、以属性的类型作为查找依据去容器中找到这个组件;如果容器中有多个这葛类型的组件,报错;
NoUniqueBeanDefinitionException:
No qualifying bean of type [com.atguigu.bean.Car] is defined:
expected single matching bean but found 2: car01,car02
2)、没找到呢?装配null
car = ioc.getBean(Car.class);
autowire="constructor":
public Person(Car car)
按照构造器进行赋值;
1)、先按照有参构造器参数的类型进行装配(成功就赋值);没有就直接为组件装配null即可。
2)、如果按照类型找到了多个;参数的名作为id继续匹配;找到就装配;找不到就null;
3)、不会报错;
自动的为属性赋值:
-->
<bean id="person" class="com.atguigu.bean.Person" autowire="byType">
</bean>
<!-- List<Book> books;容器可以把容器中的所有book封装list赋值给这个属性 -->
<bean id="book01" class="com.atguigu.bean.Book">
<property name="bookName" value="book1"></property>
</bean>
<bean id="book02" class="com.atguigu.bean.Book">
<property name="bookName" value="book2"></property>
</bean>
<bean id="book03" class="com.atguigu.bean.Book">
<property name="bookName" value="book3"></property>
</bean>
<!--
实验14:[SpEL测试I](Spring Expression Language)Spring表达式语言
在SpEL中使用字面量、
引用其他bean、
引用其他bean的某个属性值、
【 调用非静态方法
调用静态方法、】
使用运算符;都支持
-->
<bean id="person04" class="com.atguigu.bean.Person">
<!-- 字面量:${}; #{} -->
<property name="salary" value="#{12345.67*12}"></property>
<!-- 引用其他bean的某个属性值、 -->
<property name="lastName" value="#{book01.bookName}"></property>
<!-- 引用其他bean、 -->
<property name="car" value="#{car}"></property>
<!--
调用静态方法: UUID.randomUUID().toString();
#{T(全类名).静态方法名(1,2)}
-->
<property name="email" value="#{T(java.util.UUID).randomUUID().toString().substring(0,5)}"></property>
<!-- 调用非静态方法; 对象.方法名 -->
<property name="gender" value="#{book01.getBookName()}"></property>
</bean>
</beans>
================================================================================================
实验15:Spring注解@Component、@Repository、@Service、@Controller如果 Web 应用程序采用了经典的三层分层结构的话,最好在持久层、业务层和
控制层分别采用 @Repository、@Service 和 @Controller 对分层中的类进行注释,而用 @Component 对那些比较中立的类进行注释通过注解,如果一个
类带了@Service注解,将自动注册到Spring容器,不需要再在applicationContext.xml文件定义bean了,分别创建
Dao、Service、Controller★
例如:
@Controller("BookServlet01")//将本类的对象命名为BookServlet01并添加到ioc容器中,如果不命名将使用默认的名字即类名首字母小写
@Scope(value="prototype")//设置从容器中获取本类的对象时是多实例的,如果不设置,默认为单实例
public class BookServlet {
@Qualifier("bookService01")
@Autowired(required=false)
private BookService bookService;
public BookServlet(BookService bookService) {
super();
this.bookService = bookService;
}
实验16:使用context:include-filter指定扫描包时要包含的类
<context:component-scan base-package="com.gome" use-default-filters="false"><!-- 指定扫描的基础包,把基础包以及他下面的所有子包的所有加了注释的类,自动的扫描进ioc容器中 -->
<!-- 只加载某些组件,使用方法与 【context:exclude-filter】相同,但要注意的是【context:component-scan base-package="com.gome"】默认是加载全部组件需要添加【use-default-filters="false"】后本标签才会生效-->
<context:include-filter type="assignable" expression="com.gome.day01.BookService"/><!-- -->
</context:component-scan>
实验17:使用context:exclude-filter指定扫描包时不包含的类
<context:component-scan base-package="com.gome"><!-- 指定扫描的基础包,把基础包以及他下面的所有子包的所有加了注释的类,自动的扫描进ioc容器中 -->
<!-- type="annotation"指定排除规则,按照注解进行 ,标注了指定注解不要,expression为注解的全类名-->
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository"/>
<!-- type="assignable"指定排除规则,指定排除某个具体的类,expression为类的全类名-->
<context:exclude-filter type="assignable" expression="com.gome.day01.BookDao"/>
</context:component-scan>
==============================================================================================
实验18:使用@Autowired注解实现根据类型实现自动装配★
实验19:如果资源类型的bean不止一个,
默认根据@Autowired注解标记的成员变量名作为id查找bean,进行装配★
实验20:如果根据成员变量名作为id还是找不到bean,
可以使用@Qualifier注解明确指定目标bean的id★
实验21:在方法的形参位置使用@Qualifier注解
实验22:@Autowired注解的required属性指定某个属性允许不被设置
<!-- DI(依赖注入) -->
<!-- 实验18--22 -->
<context:component-scan base-package="com.gome"></context:component-scan><!-- 加载包com.gome下的所有文件-->
<!-- @Autowrite 原理:
@Qualifier("bookService01")
@Autowired
private BookService bookService;
①先按照类型去容器中查找对应的组件:bookService = (BookService) ioc.getBean(BookService.class);
①找到一个,就赋值;
②没找到,抛异常;
③找到多个,装配那个?
①把变量名作为id,继续查找;如 BookService( bookService);
@Autowired
private BookService bookService;
①找到,装配;
②没找到,报错;
原因:因为我们是按照变量名作为id进行查找;
我们可以使用【@Qualifier("bookService01")】指定一个新的id进行查找;
①找到,装配;
②没找到,报错;
【@Autowired】默认是一定要找到的,找不到就会报错,
我们可以使用【@Autowired(required=false)】让其找不到的情况下赋值为【null】
-->
</beans>
在方法和方法的形参位置使用@Autowired与@Qualifier注解
①这个方法会在bean对象创建的时候自动执行;
②这个方法中的每个形参都会自动注入
===========================================================================================
实验23:测试泛型依赖注入★
① Book.java
package com.gome.bean;
public class Book {
}
② User.java
package com.gome.bean;
public class User {
}
③ BaseDao.java
package com.gome.dao;
/**
* 定义了基本的增删改查方法
* @author lfy
*
* @param <T>
*/
public abstract class BaseDao<T> {
public abstract void save();
}
④ BookDao.java
package com.gome.dao;
import org.springframework.stereotype.Repository;
import com.gome.bean.Book;
@Repository
public class BookDao extends BaseDao<Book>{
@Override
public void save() {
// TODO Auto-generated method stub
System.out.println("BookDao....保存图书。。。");
}
}
⑤ UserDao.java
package com.gome.dao;
import org.springframework.stereotype.Repository;
import com.gome.bean.User;
@Repository
public class UserDao extends BaseDao<User>{
@Override
public void save() {
// TODO Auto-generated method stub
System.out.println("UserDao...保存用户....");
}
}
⑥ BaseService.java
package com.gome.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.gome.dao.BaseDao;
public class BaseService<T> {
@Autowired
private BaseDao<T> baseDao;
public void save(){
System.out.println("自动注入的dao:"+baseDao);
baseDao.save();
}
}
⑦ BookService.java
package com.gome.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.gome.bean.Book;
import com.gome.dao.BaseDao;
import com.gome.dao.BookDao;
@Service
public class BookService extends BaseService<Book>{
}
⑧ UserService.java
package com.gome.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.gome.bean.User;
import com.gome.dao.UserDao;
@Service
public class UserService extends BaseService<User>{
}
⑨ IOCTest.java
public class IOCTest {
@Test
public void test() {
ApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext.xml");
BookService bookService = ioc.getBean(BookService.class);
UserService userService = ioc.getBean(UserService.class);
bookService.save();
userService.save();
运行结果:
检测语言世界语中文简体中文繁体丹麦语乌克兰语乌兹别克语乌尔都语亚美尼亚语伊博语俄语保加利亚语信德语修纳语僧伽罗语克罗地亚语冰岛语加利西亚语加泰罗尼亚语匈牙利语南非祖鲁语卡纳达语卢森堡语印地语印尼巽他语印尼爪哇语印尼语古吉拉特语吉尔吉斯语哈萨克语土耳其语塔吉克语塞尔维亚语塞索托语夏威夷语威尔士语孟加拉语宿务语尼泊尔语巴斯克语布尔语(南非荷兰语)希伯来语希腊语库尔德语弗里西语德语意大利语意第绪语拉丁语拉脱维亚语挪威语捷克语斯洛伐克语斯洛文尼亚语斯瓦希里语旁遮普语日语普什图语格鲁吉亚语毛利语法语波兰语波斯尼亚语波斯语泰卢固语泰米尔语泰语海地克里奥尔语爱尔兰语爱沙尼亚语瑞典语白俄罗斯语科萨科西嘉语立陶宛语索马里语约鲁巴语缅甸语罗马尼亚语老挝语芬兰语苏格兰盖尔语苗语英语荷兰语菲律宾语萨摩亚语葡萄牙语蒙古语西班牙语豪萨语越南语阿塞拜疆语阿姆哈拉语阿尔巴尼亚语阿拉伯语韩语马其顿语马尔加什语马拉地语马拉雅拉姆语马来语马耳他语高棉语齐切瓦语 |
| 世界语中文简体中文繁体丹麦语乌克兰语乌兹别克语乌尔都语亚美尼亚语伊博语俄语保加利亚语信德语修纳语僧伽罗语克罗地亚语冰岛语加利西亚语加泰罗尼亚语匈牙利语南非祖鲁语卡纳达语卢森堡语印地语印尼巽他语印尼爪哇语印尼语古吉拉特语吉尔吉斯语哈萨克语土耳其语塔吉克语塞尔维亚语塞索托语夏威夷语威尔士语孟加拉语宿务语尼泊尔语巴斯克语布尔语(南非荷兰语)希伯来语希腊语库尔德语弗里西语德语意大利语意第绪语拉丁语拉脱维亚语挪威语捷克语斯洛伐克语斯洛文尼亚语斯瓦希里语旁遮普语日语普什图语格鲁吉亚语毛利语法语波兰语波斯尼亚语波斯语泰卢固语泰米尔语泰语海地克里奥尔语爱尔兰语爱沙尼亚语瑞典语白俄罗斯语科萨科西嘉语立陶宛语索马里语约鲁巴语缅甸语罗马尼亚语老挝语芬兰语苏格兰盖尔语苗语英语荷兰语菲律宾语萨摩亚语葡萄牙语蒙古语西班牙语豪萨语越南语阿塞拜疆语阿姆哈拉语阿尔巴尼亚语阿拉伯语韩语马其顿语马尔加什语马拉地语马拉雅拉姆语马来语马耳他语高棉语齐切瓦语 |
|
|
|
|
|