spring基础02-IOC容器2-基于xml操作bean管理
2.3 IOC操作Bean管理(基于XML)
2.3.1 什么是Bean管理
-
Bean管理指的是两个操作
-
Spring创建对象
-
Spring注入
-
2.3.2 创建对象
-
用maven创建的项目,xml配置文件放在了resources文件夹下,可以直接classpath定位到
-
<?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"> <!-- 配置User对象的创建--> <bean id="user" class="com.zhang.User"></bean> </beans>
-
bean标签的属性:
- id,唯一标识,
- class,要创建对象类的全路径,包+类
- name:和id差不多,属于早期不成熟的一个属性
-
创建对象时,默认执行的是类的无参构造,所以类必须有无参构造函数
2.3.3注入属性:(DI)
就是依赖注入( DI ) 别别人说DI别不知道是啥
-
方法1,:使用set方法注入
-
<!-- set方法注入属性--> <bean id="book" class="com.zhang.Book"> <!--在bean标签中使用property完成属性注入 name :类里面的属性名称 value:向里面注入的值 --> <property name="bname" value="java从入门到放弃"></property> </bean>
-
方法2:使用有参数构造进行注入
-
<!-- 3.有参构造创建带属性的对象--> <bean id="book1" class="com.zhang.Book"> <constructor-arg name="bname" value="php是最好的编程语言"></constructor-arg> </bean>
-
方法3:p名称空间注入(不常用)
-
<?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"> <!-- 4.是引用p命名空间注入--> <bean id="book2" class="com.zhang.Book" p:bname="Spring5冲刺50w"></bean> </beans>
-
注意第4行声明p空间
2.3.4 注入其他类型属性
a.字面量
给类的属性设置固定值,就是字面量,
-
null值
<!-- set方法注入属性--> <bean id="book" class="com.zhang.Book"> <!--在bean标签中使用property完成属性注入 name :类里面的属性名称 value:向里面注入的值 --> <property name="bname" value="java从入门到放弃"></property> <!--向属性中注入空值--> <property name="address"> <null/> </property> </bean>
-
属性值包含特殊字符
<!--向属性中注入特殊符号--> <!-- <property name="author" value="<<张>>"></property>这个写法是错的,可能把字符串里面的<>识别为xml结构体 --> <property name="author" > <value> <![CDATA[<<张>>]]> </value> </property>
- 俩中括号[ [ ] ] ,第一个中括号后面跟CDATA,第二个中括号里面写具体内容
b.注入属性-外部bean
-
创建service类和dao类
-
Dao类
-
public interface dao { public void getUser(); }
public class MyDao implements dao{ @Override public void getUser() { System.out.println("获取user"); } }
-
Service类
-
public class MyServices { private MyDao myDao; public void setMyDao(MyDao myDao) { this.myDao = myDao; } public void add(){ System.out.println("service add"); myDao.getUser();//调用dao } }
-
在service里面调用dao里面的方法
-
配置文件:
-
<bean id="myServices" class="com.zhang.service.MyServices"> <!--注入属性 name:属性名字 ref:类类型的属性值--> <property name="myDao" ref="myDao"></property> </bean> <bean id="myDao" class="com.zhang.dao.MyDao"></bean>
-
c.注入属性-内部bean和级联属性
-
一对多关系:部门&员工
-
部门类和员工类
-
public class Emp { private String ename;//员工姓名 private String gender;//性别 private Dept dept; public void setDept(Dept dept) {this.dept = dept;} public void setEname(String ename) { this.ename = ename;} public void setGender(String gender) {this.gender = gender;} }
-
public class Dept { private String danme; public void setDanme(String danme) { this.danme = danme; } }
-
配置文件:
-
<bean id="emp" class="com.zhang.bean.Emp"> <property name="ename" value="张大壮"></property> <property name="gender" value="汉子"></property> <!--设置对象类型属性--> <property name="dept"> <bean id="dept" class="com.zhang.bean.Dept"> <property name="danme" value="安保部门"></property> </bean> </property> </bean>
-
测试类
-
@Test public void test1(){ ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml"); Emp emp = context.getBean("emp", Emp.class); System.out.println(emp.toString()); }
-
-
级联赋值:像有关联的类赋值
-
配置文件:
-
<bean id="emp" class="com.zhang.bean.Emp"> <property name="ename" value="张大壮"></property> <property name="gender" value="汉子"></property> <property name="dept" ref="dept"></property> <property name="dept.dname" value="后勤部"></property> </bean> <bean id="dept" class="com.zhang.bean.Dept"></bean>
-
其他,emp类中加了一个getDept的方法
-
2.3.5 xml注入集合属性
a.基本注入方式
-
待操作类
-
public class Stu { private String[] courses;//课程 //测试List类型的属性 private List<String> list; //测试Map类型的属性 private Map<String,String > map; //测试set类型的属性 private Set<String> set; public void setSet(Set<String> set) {this.set = set;} public void setCourses(String[] courses) {this.courses = courses;} public void setList(List<String> list) {this.list = list;} public void setMap(Map<String, String> map) {this.map = map;} }
-
配置文件
-
<bean id="stu" class="collection.Stu"> <!-- 数组类型属性注入 用list或者array都可以--> <property name="courses"> <array> <value>java课程</value> <value>操作系统</value> </array> </property> <!-- List类型属性 --> <property name="list"> <list> <value>工程实践</value> <value>la</value> </list> </property> <!--map类型--> <property name="map"> <map> <entry key="JAVA" value="java"></entry> </map> </property> <!--set类型--> <property name="set"> <set> <value>张张张</value> </set> </property> </bean>
b.集合里设置对象类型值
-
配置文件
-
<beans> <bean id="stu" class="collection.Stu"> <!-- 注入list集合类型,值是对象--> <property name="courseList"> <list> <ref bean="java"></ref> <ref bean="database"></ref> </list> </property> </bean> <bean id="java" class="collection.Course"> <property name="cname" value="java"></property> </bean> <bean id="database" class="collection.Course"> <property name="cname" value="database"></property> </bean> </beans>
-
Stu类和course类
-
public class Course { private String cname;//课程名称 public void setCname(String cname) { this.cname = cname;} }
-
public class Stu { private List<Course> courseList; public void setCourseList(List<Course> courseList) { this.courseList = courseList;} }
c.把集合注入部分提取出公共部分
-
在spring配置文件中引入名称空间 util
-
<?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" 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.xsd">
-
多加了一个xmlns:util 同之前p名称的改法,location里面多了两个连接,将原连接里的所有beans改成util
-
配置文件:
-
<!--提取list集合类型属性注入--> <util:list id="bookList"> <value>钢铁是怎样练成的</value> <value>降龙十八掌</value> </util:list> <!-- 使用--> <bean id="book" class="collection.Book"> <property name="list" ref="bookList"></property> </bean>
-
Book类
-
public class Book { private List<String> list; public void setList(List<String> list) {this.list = list;} }
2.3.6 FactoryBean
- Spring 有两种类型的bean,一种普通的bean,另外一种就是工厂bean
- 普通bean:在配置文件中定义bean类型就是返回类型
- 工厂bean:可以不一样
- 创建类,让这个类作为工厂bean,实现接口FactoryBean
- 实现接口里面的方法,在实现方法中定义返回的bean类型
public class MyBean implements FactoryBean<Course> {
//定义一下返回的bean的类型
@Override
public Course getObject() throws Exception {
Course course = new Course();
course.setCname("英语");
return course;
}
@Override
public Class<?> getObjectType() {
return null;
}
@Override
public boolean isSingleton() {
return FactoryBean.super.isSingleton();
}
}
测试类:
public void test2(){
ApplicationContext context = new ClassPathXmlApplicationContext("bean-factorybean.xml");
Course course = context.getBean("mybean", Course.class);
System.out.println(course);
}
2.3.7 bean作用域
-
在spring里,设置创建的bean实例是单实例还是多实例
-
在spring里面,默认情况下创建的bean是一个单实例情况
- 可以多次context.getbean() ,但是拿出来的对象hashcode都是一个
-
设置:
-
spring配置文件的bean标签里可以设置scope属性
-
<bean id="book" class="collection.Book" scope="prototype"></bean><!--多实例--> bean id="book" class="collection.Book" scope="singleton"></bean><!--单实例:默认的-->
-
设置成singleton时,加载spring配置文件时就会创建单实例对象
-
设置成prototype时,在调用getBean方法时才创建对象
-
2.3.8 bean声明周期
- 一个对象从创建到对象销毁的过程
- bean的声明周期
- 第一步:通过构造器创建bean实例(无参构造)
- 第二步:为bean的属性设置值和对其他bean引用(调用set方法)
- (后置处理器)把bean的实例传给bean后置处理器的方法postProcessBeforeInitialization
- 第三步:调用bean的初始化方法(需要进行配置)
- (后置处理器)把bean的实例传给bean后置处理器的方法postProcessAfterInitialization
- 第四步:bean可以使用了
- 第五步:当容器关闭的时候,调用bean的销毁的方法(需要进行配置销毁的方法)
bean类:
public class Order {
private String oname;
public void setOname(String oname) {
this.oname = oname;
System.out.println("第二步,set方法设置值");
}
public Order() {
System.out.println("第一步,无参构造");
}
//创建执行初始化的方法
public void initMethod(){
System.out.println("第三部,初始化方法");
}
public void destroyMethod(){
System.out.println("第五步,销毁bean");
}
}
配置文件:注意配置了初始化方法和销毁方法
<bean id="orders" class="bean.Order" init-method="initMethod" destroy-method="destroyMethod">
<property name="oname" value="手机"></property>
</bean>
测试方法,调用了context的close方法
注意:ApplicationContext是个接口,没有close方法, 得强转成new 的ClassPathXmlApplicationContext类型,或者把context声明成这个类型
@Test
public void test3(){
ApplicationContext context = new ClassPathXmlApplicationContext("bean-factorybean.xml");
Order orders = context.getBean("orders", Order.class);
System.out.println("第四步,获取创建bean实例对象");
System.out.println(orders);
((ClassPathXmlApplicationContext)context).close();
}
- bean的后置处理器
- 创建类,实现BeanPostProcessor,创建后置处理器
public class PostProcess implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("执行后置处理方法1");
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("执行后置处理方法2");
return bean;
}
}
配置文件:
他会为这个配置文件下的每一个bean实例都添加后置处理
<bean id="postprocess" class="bean.PostProcess"></bean>
测试方法:
测试的还是用上一个Order实例
@Test
public void test3(){
ApplicationContext context = new ClassPathXmlApplicationContext("bean-factorybean.xml");
Order orders = context.getBean("orders", Order.class);
System.out.println("第四步,获取创建bean实例对象");
System.out.println(orders);
((ClassPathXmlApplicationContext)context).close();
}
2.3.2.9 xml自动装配(一键白学)
-
啥是手动装配
- 就是在配置文件里通过value和ref设置每个属性的值
-
根据指定装配规则(属性名称或者属性类型)Spring自动将匹配的属性进行注入
- F---K,有这玩意前面十几节学他干毛
-
根据名称byName
-
配置文件
-
-
bean类
-
public class Emp { private Dept dept; public void setDept(Dept dept) {this.dept = dept;} @Override public String toString() {return "Emp{" +"dept=" + dept +'}';} }
-
public class Dept { @Override public String toString() { return "Dept{}";} }
-
测试类测试Emp的创建,略
-
-
根据类型:byType
- 就是去你的配置文件里面找到合适的类型的bean注入,但是注意,必须要保证唯一
- 比如上面例子要是声明了俩 class="Dept"的bean就不好使了,就必须使用byName了
2.3.10 外部属性文件
把一些常用的固定的值,放在一个外部文件中,然后导入xml配置文件
就好像把常量抽取出来组成一个常量类一样
- 方法1:直接配置数据库信息
- 配置德鲁伊连接池
- 引入依赖jar包
<!-- 直接配置连接池-->
<bean id="druid" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306"></property>
<property name="username" value="root"></property>
<property name="password" value="072432"></property>
</bean>
-
方法2:引入外部属性文件配置数据库连接池
-
创建外部属性文件,jdbc.properties
-
prop.driverClassName=com.mysql.jdbc.Driver prop.url=jdbc:mysql://localhost:3306 prop.username=root prop.password=072432
-
把外部properties属性文件引入到spring配置文件中
-
引入名称空间context,方法同util空间
-
<?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">
-
在spring配置文件中使用标签引入外部属性文件
-
<context:property-placeholder location="jdbc.properties"/>
-
<!-- 使用外部属性文件--> <context:property-placeholder location="jdbc.properties"/> <bean id="druid" class="com.alibaba.druid.pool.DruidDataSource"> <property name="driverClassName" value="${prop.driverClassName}"></property> <property name="url" value="${prop.url}"></property> <property name="username" value="${prop.username}"></property> <property name="password" value="${prop.password}"></property> </bean>
-
-
本文来自博客园,作者:荧惑微光,转载请注明原文链接:https://www.cnblogs.com/yinghuoweiguang/p/16019002.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· DeepSeek在M芯片Mac上本地化部署
· 葡萄城 AI 搜索升级:DeepSeek 加持,客户体验更智能