1. HelloWorld
三个步骤:
1.创建类
2.配置xml文件
3.通过xml文件使得bean实列化
1. 创建类
java
package com.itgyl.bean;
public class HelloWorld {
public HelloWorld() {
System.out.println("1.通过无参构造创建对象");
}
public void hello() {
System.out.println("hello world");
}
}
2. 配置xml文件
XML
<?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 id="helloWorld" class="com.itgyl.bean.HelloWorld"></bean>
<!--如果对同一个类配置两次bean会报错:
org.springframework.beans.factory.NoUniqueBeanDefinitionException:
No qualifying bean of type 'com.itgyl.bean.HelloWorld' available:
expected single matching bean but found 2: helloWorld,hello-->
<!--<bean id="hello" class="com.itgyl.bean.HelloWorld"></bean>-->
</beans>
3. bean实例化
java
@Test
public void testHello() {
//1.配置xml配置信息
//2.通过xml配置信息获取管理对象的IOC容器
ApplicationContext ac =
new ClassPathXmlApplicationContext("bean.xml");
//3.通过bean.xml中的配置信息将类实例化
HelloWorld hw = (HelloWorld) ac.getBean("helloWorld");
System.out.print("2.配置信息创建对象:");
hw.hello();
logger.info("执行成功,打印日志");
}
2. 实例化bean的三种方式
java
@Test
public void testGetBean() {
//通过xml获取管理对象IOC容器
ApplicationContext ac =
new ClassPathXmlApplicationContext("bean.xml");
//1.通过id获取bean对象
HelloWorld hw1 = (HelloWorld) ac.getBean("helloWorld");
System.out.print("通过id获取bean实例化对象:");
hw1.hello();
//2.通过class类获取bean对象
HelloWorld hw2 = ac.getBean(HelloWorld.class);
System.out.print("通过class获取bean实例化对象");
hw2.hello();
//3.通过id和class类获取bean实例化对象
HelloWorld hw3 = ac.getBean("helloWorld", HelloWorld.class);
System.out.print("通过id和class获取bean实例化对象");
hw3.hello();
}
注意事项
当接口被多个bean实现时无法通过接口调用实例化bean的方法
java
package com.itgyl.bean;
public class StudentDao implements UserDao{
@Override
public void run() {
System.out.println("student run");
}
}
java
package com.itgyl.bean;
public class PersonDao implements UserDao{
@Override
public void run() {
System.out.println("person run");
}
}
java
@Test
public void testDetail() {
ApplicationContext ac =
new ClassPathXmlApplicationContext("bean.xml");
/***
* 当接口只有唯一一个bean实现时可以通过接口调用bean的方法
* 当接口被多个类同时实现时无法通过接口调用bean的方法,此时接口不知道调用哪个bean重写的方法
*/
System.out.println("报错:一个接口被多个类同时实现无法通过接口调用方法,此时接口不知道调用哪个类的方法");
UserDao ud = ac.getBean(UserDao.class);
ud.run();
}
如果组件类实现了接口,根据接口类型可以获取 bean 吗?
> 可以,前提是bean唯一
如果一个接口有多个实现类,这些实现类都配置了 bean,根据接口类型可以获取 bean 吗?
> 不行,因为bean不唯一
3. bean属性值赋值方式
3.1 setter方式注入
<!-- 1.set方式注入 property标签:通过set和get方法对对象进行属性赋值 name: 为对象的属性名 value:为对象的属性值 -->
此时会先通过无参构造创建实例化对象,再通过bean中的set方法进行赋值
XML
<bean id="student1" class="com.itgyl.di.Student">
<property name="studentName" value="zhangsan"></property>
<property name="age" value="18"></property>
</bean>
3.2 constructor方式注入
<!-- 2.constructor方式注入 constructor-arg标签:通过构造方法使对象实例化 可通过index:index下标从0开始,对应构造方法第一个属性,以此类推 可通过name:赋值可property一致 -->
此时通过有参构造直接进行赋值,所有有参构造器必须实现
XML
<bean id="student2" class="com.itgyl.di.Student">
<constructor-arg name="studentName" value="lisi"></constructor-arg>
<constructor-arg name="age" value="19"></constructor-arg>
</bean>
4. 特殊值处理方式
<!-- 特殊值: 1.字面常量值:如10,20... 2.null值:通过null标签进行赋值 3.xml实体:在html中有些符号有特殊符号需要转义。如:尖括号<>:转移后< h1 > 4.![CDATA[]]
- null值需通过标签进行赋值,如果此时value="null"即赋值为字符串null而不是空值
XML
<bean id="student3" class="com.itgyl.di.Student">
<property name="studentName"><null></null></property>
<property name="age" value="18"></property>
</bean>
3.xml配置文件使用前端标签进行配置,有些符号有特殊含义,故需要通过转义字符进行转义
XML
<bean id="student3" class="com.itgyl.di.Student">
<property name="studentName" value="< hello >"></property>
</bean>
4.通过 !CDATA[ 值 ]] 方式赋值
XML
<bean id="student3" class="com.itgyl.di.Student">
<property name="studentName">
<value><![CDATA[ hello ]]></value>
</property>
</bean>
5. bean属性赋值
5.1 为bean属性为对象赋值
bean中有属性为对象时,若要为该属性赋值需通过ref进行引入,若直接通过value赋值会报错
定义两个类
java
public class Emp {
private Dept dept;
private String empName;
private int id;
java
public class Dept {
private String deptName;
private int deptId;
private List<Emp> list;
- 外部引入bean
XML
<!--
1.外部引入bean
-->
<bean id="dept1" class="com.itgyl.beandi.Dept">
<!--注入普通属性值-->
<property name="deptName" value="开发部"></property>
<property name="deptId" value="10086"></property>
</bean>
<bean id="emp1" class="com.itgyl.beandi.Emp">
<!--注入对象属性值,需要使用ref即从什么地方引用-->
<property name="dept" ref="dept1"></property>
</bean>
- 内部引入bean
XML
<!--
2.内部引入bean
-->
<bean id="emp2" class="com.itgyl.beandi.Emp">
<!--注入对象属性值,内部引入-->
<property name="dept">
<bean class="com.itgyl.beandi.Dept" id="dept2">
<property name="deptName" value="管理部"></property>
<property name="deptId" value="10088"></property>
</bean>
</property>
<!--注入普通属性值-->
<property name="empName" value="张三"></property>
<property name="id" value="007"></property>
</bean>
- 级联赋值
XML
<!--
3.级联赋值
-->
<bean class="com.itgyl.beandi.Dept" id="dept3">
<property name="deptName" value="鸡术研发部"></property>
</bean>
<bean class="com.itgyl.beandi.Emp" id="emp3">
<property name="empName" value="王五"></property>
<!--级联赋值中先引入bean才能进行赋值-->
<property name="dept" ref="dept3"></property>
<property name="dept.deptName" value="技术研发部"></property>
</bean>
5.2 为bean属性为数组赋值
XML
<!--给对象中的数组赋值-->
<bean class="com.itgyl.beandi.People" id="people">
<property name="hobby">
<!--给数组赋值需要用到标签<array>-->
<array>
<value>吃饭</value>
<value>睡觉</value>
<value>打游戏</value>
</array>
</property>
</bean>
5.3 为bean属性为集合赋值
5.3.1 为List集合赋值
java
public class Dept {
private String deptName;
private int deptId;
private List<Emp> list;
XML
<!--配置两个bean实例化对象-->
<bean class="com.itgyl.beandi.Emp" id="emp1">
<property name="empName" value="张三"></property>
<property name="id" value="001"></property>
</bean>
<bean class="com.itgyl.beandi.Emp" id="emp2">
<property name="empName" value="李四"></property>
<property name="id" value="007"></property>
</bean>
<bean class="com.itgyl.beandi.Dept" id="dept">
<!--注入集合:加上<list>标签即可,若集合中的值是对象,用ref引入对象即可,在通过bean指定具体的对象-->
<property name="list">
<list>
<ref bean="emp1"></ref>
<ref bean="emp2"></ref>
</list>
</property>
</bean>
5.3.2 为Map集合赋值
java
public class Teacher {
private String name;
private Map<String, People> map;
XML
<bean class="com.itgyl.beandi.People" id="people1">
<property name="name" value="张三"></property>
<property name="age" value="18"></property>
</bean>
<bean class="com.itgyl.beandi.People" id="people2">
<property name="name" value="李四"></property>
<property name="age" value="19"></property>
</bean>
<!--配置带有map的bean-->
<bean class="com.itgyl.beandi.Teacher" id="teacher">
<property name="name" value="仓老师"></property>
<!--注入map数据需要用到<map>标签,在map标签中注入具体键值对用<entry>标签-->
<property name="map">
<map>
<entry key="仓老师" value-ref="people1"></entry>
<entry key="三上老师" value-ref="people2"></entry>
</map>
</property>
</bean>
5.3.3 引用集合赋值
XML
<?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:util="http://www.springframework.org/schema/util"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--通过util:list可直接为集合注入值-->
<util:list id="list">
<ref bean="emp1"></ref>
<ref bean="emp2"></ref>
</util:list>
<!--通过util:map可直接为集合注入值-->
<util:map id="map">
<entry key="仓老师" value-ref="emp1"></entry>
<entry key="三上老师" value-ref="emp2"></entry>
</util:map>
<bean class="com.itgyl.beandi.ListMap" id="listMap">
<!--上面已经定义了集合list和map此时通过引入直接将集合的属性值注入到该bean中,即完成集合属性注入-->
<property name="list" ref="list"></property>
<property name="map" ref="map"></property>
</bean>
6. 命名空间
<!-- 引入命名空间,即在xmls:名称="http://www.springframework.org/schema/名称" 可直接通过命名空间直接为bean注入属性值 -->
XML
<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"
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean class="com.itgyl.beandi.Emp" id="emp1" p:empName="zhangsan" p:id="10096"></bean>
<bean class="com.itgyl.beandi.Emp" id="emp2" p:empName="lisi" p:id="10011"></bean>
</beans>
7. 引入外部文件
通过location进行引入外部文件
配置引入文件
XML
jdbc.user=root
jdbc.password=123456
jdbc.url=jdbc:mysql://localhost:3306/ssm?serverTimezone=UTC
jdbc.driver=com.mysql.cj.jdbc.Driver
XML
<?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.xsd">
<!--引入外部文件-->
<context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
<bean class="com.alibaba.druid.pool.DruidDataSource" id="dataSource">
<property name="url" value="${jdbc.url}"/>
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="username" value="${jdbc.user}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
</beans>
8. bean的作用域
bean的作用域: 默认使用singleton,即在该IoC容器中该bean始终为单实例化,执行时机为IoC容器创建时 prototype,即在该IoC容器中有多个实例,执行时机为获取bean时 可通过scope进行配置
XML
<bean class="com.itgyl.beandi.User" id="user" scope="singleton"
init-method="initMethod" destroy-method="destroyMethod"></bean>
9. bean的生命周期
<!--bean的生命周期:IoC容器关闭之前有效,bean的实例化默认是单实列singleton--> <!--bean初始化的步骤 1.通过无参构造创建实例化对象 2.给bean设置属性值 3.bean调用后置处理器之前:调用初始化方法之前 4.调用intiMethod初始化方法 5.bean调用后置处理器之后:调用初始化方法之后 6.完成bean的实例化 7.bean调用destroyMethod销毁方法 8.IoC容器关闭-->
java
public class User implements BeanPostProcessor{
private String name;
private String password;
private void destroyMethod() {
System.out.println("7 bean实列销毁");
}
private void initMethod() {
System.out.println("4 bean实列初始化");
}
public User() {
System.out.println("1 bean通过无参构造进行初始化");
}
java
public class myBeanProcess implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("3 bean后置处理器执行之前");
System.out.println("☆☆☆" + beanName + " = " + bean);
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("5 bean后置处理器执行之后");
System.out.println("★★★" + beanName + " = " + bean);
return bean;
}
}
XML
<bean class="com.itgyl.beandi.User" id="user" scope="singleton"
init-method="initMethod" destroy-method="destroyMethod"></bean>
<!--后置处理器不是对单独一个bean有效,对IoC容器所有的bean都生效-->
<bean class="com.itgyl.beandi.myBeanProcess" id="myBeanProcess"></bean>
最终执行结果为1、2、3、4、5、6、7、8的打印语句
10. 基于XML自动装配
加入autowire配置
autowire="byType"即通过类型自动装配
autowire="byName"即通过变量名进行自动装配,此时变量名为什么id名也必须保持一致
java
public class UserController {
private UserService userService;
public void setUserServiceImp(UserServiceImp userServiceImp) {
this.userService = userServiceImp;
}
public void show() {
userService.show();
}
}
java
public class UserServiceImp implements UserService{
private UserDaoImp userDaoImp;
public void setUserDaoImp(UserDaoImp userDaoImp) {
this.userDaoImp = userDaoImp;
}
@Override
public void show() {
userDaoImp.show();
}
}
java
public class UserDaoImp implements UserDao{
@Override
public void show() {
System.out.println("自动装配实现");
}
}
XML
<?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">
<!--autowire自动装配根据类型自动进行属性注入-->
<bean id="userController" class="com.itgyl.auto.controller.UserController" autowire="byType"></bean>
<bean id="userServiceImp" class="com.itgyl.auto.service.UserServiceImp" autowire="byType"></bean>
<bean id="userDaoImp" class="com.itgyl.auto.dao.UserDaoImp" autowire="byType"></bean>
</beans>
java
@Test
public void testAuto() {
//通过xml文件获取管理对象的IoC容器
ApplicationContext context =
new ClassPathXmlApplicationContext("auto.xml");
UserController userController = context.getBean("userController", UserController.class);
userController.show();
}