当前位置: 首页 > news >正文

Spring:IoC容器(基于XML管理bean)

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中有些符号有特殊符号需要转义。如:尖括号<>:转移后&lt; h1 &gt
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="&lt; hello &gt;"></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();}

相关文章:

  • J.搬砖【蓝桥杯】/01背包+贪心
  • Redis 常用基本命令
  • 端口扫描利器--nmap
  • 使用 Django Rest Framework 构建强大的 Web API
  • Android Studio | 小白如何运行别人的安卓项目
  • dp秒杀优惠券
  • k8s部署calico遇到的问题
  • python -【四】函数
  • 2024华为OD机试真题-素数之积-C++-OD统一考试(C卷D卷)
  • Textual for Mac:轻量级IRC客户端
  • 安卓赤拳配音v1.0.2Ai配音神器+百位主播音色
  • Rust一维Vec垂直方向拼接、水平方向拼接,多个二维Vec垂直方向拼接
  • STM32-13-MPU
  • Linux内核编译流程3.10
  • 24V_2A_1.2MHZ|PCD0303升压恒频LCD背光源专用电路超小体积封装
  • Google 是如何开发 Web 框架的
  • JavaScript 一些 DOM 的知识点
  • Java小白进阶笔记(3)-初级面向对象
  • Js基础——数据类型之Null和Undefined
  • MySQL的数据类型
  • Python连接Oracle
  • Selenium实战教程系列(二)---元素定位
  • Spring Boot快速入门(一):Hello Spring Boot
  • 通过几道题目学习二叉搜索树
  • ​云纳万物 · 数皆有言|2021 七牛云战略发布会启幕,邀您赴约
  • (4)Elastix图像配准:3D图像
  • (delphi11最新学习资料) Object Pascal 学习笔记---第2章第五节(日期和时间)
  • (function(){})()的分步解析
  • (javascript)再说document.body.scrollTop的使用问题
  • (void) (_x == _y)的作用
  • (附源码)ssm经济信息门户网站 毕业设计 141634
  • (黑客游戏)HackTheGame1.21 过关攻略
  • (转)setTimeout 和 setInterval 的区别
  • .NET CLR Hosting 简介
  • .net framework 4.0中如何 输出 form 的name属性。
  • @column注解_MyBatis注解开发 -MyBatis(15)
  • [3D游戏开发实践] Cocos Cyberpunk 源码解读-高中低端机性能适配策略
  • [AMQP Connection 127.0.0.1:5672] An unexpected connection driver error occured
  • [CentOs7]搭建ftp服务器(2)——添加用户
  • [C和指针].(美)Kenneth.A.Reek(ED2000.COM)pdf
  • [echarts] y轴不显示0
  • [Firefly-Linux] RK3568 pca9555芯片驱动详解
  • [Firefly-Linux] RK3568修改控制台DEBUG为普通串口UART
  • [k8s系列]:kubernetes·概念入门
  • [MSSQL]GROUPING SETS,ROLLUP,CUBE初体验
  • [poj 3461]Oulipo[kmp]
  • [Spring]一文明白IOC容器和思想
  • [SpringBoot系列]NoSQL数据层解决方案
  • [TroubleShooting]CentOS8使用pyenv部署多版本python时报 python: command not found
  • [Windows] 植物大战僵尸杂交版
  • [笔记] 四边形不等式
  • [机缘参悟-118] :如何做到:从无到有,从0到1设计一个新系统或产品?如何做到总是能快速的解决复杂技术难题?
  • [技术][.NET]一步一步学Linq to sql -- Joney Liu博客园整理
  • [免费专栏] Android安全之检测APK中调试代码是否暴露敏感信息
  • [面试]我们常说的负载均衡是什么东西?