1. HelloWorld
三个步骤:
1.创建类
2.配置xml文件
3.通过xml文件使得bean实列化
1. 创建类
package com.itgyl.bean;public class HelloWorld {public HelloWorld() {System.out.println("1.通过无参构造创建对象");}public void hello() {System.out.println("hello world");}
}
2. 配置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实例化
@Testpublic 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的三种方式
@Testpublic 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的方法
package com.itgyl.bean;public class StudentDao implements UserDao{@Overridepublic void run() {System.out.println("student run");}
}
package com.itgyl.bean;public class PersonDao implements UserDao{@Overridepublic void run() {System.out.println("person run");}
}
@Testpublic 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方法进行赋值
<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一致 -->此时通过有参构造直接进行赋值,所有有参构造器必须实现
<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[]]
2. null值需通过标签进行赋值,如果此时value="null"即赋值为字符串null而不是空值
<bean id="student3" class="com.itgyl.di.Student"><property name="studentName"><null></null></property><property name="age" value="18"></property></bean>
3.xml配置文件使用前端标签进行配置,有些符号有特殊含义,故需要通过转义字符进行转义
<bean id="student3" class="com.itgyl.di.Student"><property name="studentName" value="< hello >"></property></bean>
4.通过 !CDATA[ 值 ]] 方式赋值
<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赋值会报错
定义两个类
public class Emp {private Dept dept;private String empName;private int id;
public class Dept {private String deptName;private int deptId;private List<Emp> list;
1. 外部引入bean
<!--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>
2. 内部引入bean
<!--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>
3. 级联赋值
<!--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属性为数组赋值
<!--给对象中的数组赋值--><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集合赋值
public class Dept {private String deptName;private int deptId;private List<Emp> list;
<!--配置两个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集合赋值
public class Teacher {private String name;private Map<String, People> map;
<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 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/utilhttp://www.springframework.org/schema/util/spring-util.xsdhttp://www.springframework.org/schema/beanshttp://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注入属性值 -->
<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/beanshttp://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进行引入外部文件
配置引入文件
jdbc.user=root
jdbc.password=123456
jdbc.url=jdbc:mysql://localhost:3306/ssm?serverTimezone=UTC
jdbc.driver=com.mysql.cj.jdbc.Driver
<?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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://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进行配置
<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容器关闭-->
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通过无参构造进行初始化");}
public class myBeanProcess implements BeanPostProcessor {@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {System.out.println("3 bean后置处理器执行之前");System.out.println("☆☆☆" + beanName + " = " + bean);return bean;}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {System.out.println("5 bean后置处理器执行之后");System.out.println("★★★" + beanName + " = " + bean);return bean;}
}
<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名也必须保持一致
public class UserController {private UserService userService;public void setUserServiceImp(UserServiceImp userServiceImp) {this.userService = userServiceImp;}public void show() {userService.show();}
}
public class UserServiceImp implements UserService{private UserDaoImp userDaoImp;public void setUserDaoImp(UserDaoImp userDaoImp) {this.userDaoImp = userDaoImp;}@Overridepublic void show() {userDaoImp.show();}
}
public class UserDaoImp implements UserDao{@Overridepublic void show() {System.out.println("自动装配实现");}
}
<?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>
@Testpublic void testAuto() {//通过xml文件获取管理对象的IoC容器ApplicationContext context =new ClassPathXmlApplicationContext("auto.xml");UserController userController = context.getBean("userController", UserController.class);userController.show();}