3.介绍Bean在spring容器中的管理方式(xml) 手动装配
xml的方法太过于低效,感觉意义不大,了解一下就可以了,重要的是注解开发
第一步我们写好一个user类
public class User
{
public void add(){
System.out.println("我加了");
}
}
然后我们在src包下 写xml文件 bean1.xml
<!-- 配置user对象创建-->
<bean id="user" class="com.xyq.spring_1.User"></bean>
并且写一个测试类
@Test
public void testAdd(){
//1.加载spring配置文件
// 这个函数和类就用到了spring框架
// IOC两大接口 1. BeanFactory 2. Applicationcontext
ApplicationContext context =new ClassPathXmlApplicationContext("bean1.xml");
// 2.获取配置 创建文件
User user = context.getBean("user", User.class);
System.out.println(user);
user.add();
}
我们可以发现context的引用方式可以有1. BeanFactory 2. Applicationcontext两种,并且我们要注意好xml文件的地址
这个也是spring管理bean的基本流程
① 使用set 来给bean赋值
有如下Book类
public class Book {
private String bname;
private String author;
private String address;
public void setBname(String bname) {
this.bname = bname;
}
public void setAuthor(String author) {
this.author = author;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "Book{" +
"bname='" + bname + '\'' +
", author='" + author + '\'' +
"address" +" " +address+
'}';
}
public String getBname() {
return bname;
}
public String getAuthor() {
return author;
}
}
xml 文件
<bean id ="book" class ="com.xyq.spring_1.Book">
<property name="author" value="xyq"></property>
<property name="bname" value="wdnmd"></property>
<!--<property name="address" >-->
<!--<null/>-->
<!--</property>-->
<property name="address" >
<value> <![CDATA[<<南京>>]]>
</value>
</property>
</bean>
测试类
@Test
public void test2(){
//1.加载spring配置文件
// 这个函数和类就用到了spring框架
// IOC两大接口 1. BeanFactory 2. Applicationcontext
ApplicationContext context =new ClassPathXmlApplicationContext("bean1.xml");
// 2.获取配置 创建文件
Book book = context.getBean("book", Book.class);
System.out.println(book);
}
即 用 property 来赋值 并且要有对应的set方法,并且要获取得到其引用
② 使用 有参构造方法 赋值bean
有一下order类
public class Order {
private String oName;
private String oFee;
public Order(String oName, String oFee) {
this.oName = oName;
this.oFee = oFee;
}
@Override
public String toString() {
return "Order{" +
"oName='" + oName + '\'' +
", oFee='" + oFee + '\'' +
'}';
}
}
注意该类的无参构造方法已被覆盖
所以xml文件编写的方式也不大一样
xml文件
<bean id ="order" class ="com.xyq.spring_1.Order">
<constructor-arg name="oName" value="ojk"></constructor-arg>
<constructor-arg name="oFee" value="osjk"></constructor-arg>
</bean>
测试类
@Test
public void test3(){
ApplicationContext context =new ClassPathXmlApplicationContext("bean1.xml");
Order order = context.getBean("order", Order.class);
System.out.println(order);
}
可以注意到不过是标签有区别而已
③ 使用P命名空间来给bean赋值
我们依然用到Book类
如下
public class Book {
private String bname;
private String author;
private String address;
public void setBname(String bname) {
this.bname = bname;
}
public void setAuthor(String author) {
this.author = author;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "Book{" +
"bname='" + bname + '\'' +
", author='" + author + '\'' +
"address" +" " +address+
'}';
}
public String getBname() {
return bname;
}
public String getAuthor() {
return author;
}
}
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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
我们添加了其中的
xmlns:p=“http://www.springframework.org/schema/p”
是由上列的xsi改的
然后
<bean id ="book1" class ="com.xyq.spring_1.Book" p:author="大力" p:bname="抢劫">
</bean>
xml只要这样写就方便了很多了
这边给出测试类
@Test
public void test4(){
ApplicationContext context =new ClassPathXmlApplicationContext("bean1.xml");
Book book1 = context.getBean("book1", Book.class);
System.out.println(book1);
}
④ 注入空值和特殊符号
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BZ3VthrX-1606220314639)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20201121233111104.png)]
如图 不过是加一个null标签
特殊符号:1.查找对应的转义符号
比如< 对应 <之类的
2.写进cData标签内
<property name="address" >
<value> <![CDATA[<<南京>>]]>
</value>
</property>
⑤ 注入外部bean
以如下结构建立文件
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-McB007x3-1606220314644)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20201121233459045.png)]
下面给出对应文件代码
UserDao
public interface UserDao {
public void update();
}
UserDaoImpl
public class UserDaoImpl implements UserDao {
public void update(){
System.out.println("Dao updated too");
}
}
UserService
public class UserService {
// 创建userDao类型属性, 生产set方法
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public void add(){
System.out.println("I am created");
//原始方式
// UserDao userDao =new UserDaoImpl();
// userDao.update();
//2
userDao.update();
}
}
xml
<!--创建service 和dao 对象 -->
<bean id="userService" class="com.xyq.spring_1.service.UserService">
<property name="userDao" ref="userDaoImp"></property>
</bean>
<!--注入userDao的对象 -->
<bean id="userDaoImp" class="com.xyq.spring_1.dao.UserDaoImpl"></bean>
测试类
@Test
public void testAdd(){
ApplicationContext context =new ClassPathXmlApplicationContext("bean2.xml");
UserService userService = context.getBean("userService", UserService.class);
userService.add();
}
这样就可以注入外部bean了
⑥ 内部bean
如下结构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xqcS02AW-1606220314646)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20201121233841196.png)]
Dept
public class Dept {
private String dName;
public void setdName(String dName) {
this.dName = dName;
}
@Override
public String toString() {
return "Dept{" +
"dName='" + dName + '\'' +
'}';
}
}
emp
public class Emp {
private String eName;
private String gender;
private Dept dept;
public void setDept(Dept dept) {
this.dept = dept;
}
public Dept getDept() {
return dept;
}
public void seteName(String eName) {
this.eName = eName;
}
public void setGender(String gender) {
this.gender = gender;
}
@Override
public String toString() {
return "Emp{" +
"eName='" + eName + '\'' +
", gender='" + gender + '\'' +
", dept=" + dept +
'}';
}
}
xml类
<!--内部bean-->
<bean id="emp" class="com.xyq.spring_1.Bean.Emp">
<property name="eName" value="wsz"></property>
<property name="gender" value="女"></property>
<property name="dept" >
<bean id="dept" class="com.xyq.spring_1.Bean.Dept">
<property name="dName" value="保安保护不了任何人"></property>
</bean>
</property>
</bean>
测试类
@Test
public void testInnerBean(){
ApplicationContext context =new ClassPathXmlApplicationContext("bean3.xml");
Emp emp = context.getBean("emp", Emp.class);
System.out.println(emp);
}
⑦级联赋值
类依旧使用dept和emp类
xml
<!--级联赋值-->
<bean id="emp" class="com.xyq.spring_1.Bean.Emp">
<property name="eName" value="wsz"></property>
<property name="gender" value="女"></property>
<!--级联赋值-->
<property name="dept" ref="dept"></property>
<property name="dept.dName" value="技术部"></property>
</bean>
<bean id="dept" class="com.xyq.spring_1.Bean.Dept">
<!--<property name="dName" value="财务部"></property>-->
</bean>
我们可以看出,使用ref来连接外部bean 后
有两种方式对级联 低级bean 的属性赋值
一种在低级bean中使用 property标签
另一种在高级bean中直接
但是前提是emp类可以获取到dept对象
⑧ 给bean附集合,数组属性
有stu类
public class Stu {
private String[] subjct;
private List<String> list;
private List<Course> course;
private Map<String, String> maps;
private Set<String> set;
public Stu() {
}
public void setSet(Set<String> set) {
this.set = set;
}
public void setList(List<String> list) {
this.list = list;
}
public void setCourse(List<Course> course) {
this.course = course;
}
public void setMaps(Map<String, String> maps) {
this.maps = maps;
}
public void setSubjct(String[] subjct) {
this.subjct = subjct;
}
public String toString() {
return "Stu{subjct=" + Arrays.toString(this.subjct) + ", list=" + this.list + ", course=" + this.course + ", maps=" + this.maps + ", set=" + this.set + '}';
}
}
course类
public class Course {
private String cName;
public Course() {
}
public void setcName(String cName) {
this.cName = cName;
}
public String toString() {
return "Course{cName='" + this.cName + '\'' + '}';
}
}
book类
public class Book {
private List<String> list;
public Book() {
}
public void setList(List<String> list) {
this.list = list;
}
public String toString() {
return "Book{list=" + this.list + '}';
}
}
<!--注入集合赋值-->
<bean id="stu" class="com.xyq.spring_1.TestDemo.collectionBean.Stu">
<!--数组-->
<property name="subjct" >
<array>
<value>mysql</value>
<value>java</value>
</array>
</property>
<property name="list">
<list>
<value>长大</value>
<value>变小</value>
</list>
</property>
<property name="maps">
<map>
<entry key="刘德华" value="无间道"></entry>
<entry key="陈建仁" value="无间地狱"></entry>
</map>
</property>
<property name="set">
<set>
<value>okoko</value>
<value>ditjgj</value>
</set>
</property>
<property name="course">
<list>
<ref bean="course1"></ref>
<ref bean="course2"></ref>
</list>
</property>
</bean>
<bean id="course1" class="com.xyq.spring_1.TestDemo.collectionBean.Course">
<property name="cName" value="iygf"></property>
</bean>
<bean id="course2" class="com.xyq.spring_1.TestDemo.collectionBean.Course">
<property name="cName" value="ddhgf"></property>
</bean>
我们可以发现bean中的集合 可以赋值基本属性,也可以赋值对象,区别是基本属性用value ,对象则需要在外部创建,并且用ref引用
测试类
@Test
public void testAdd() {
ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
Stu stu = (Stu)context.getBean("stu", Stu.class);
System.out.println(stu);
}
@Test
public void test01() {
ApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml");
Book book = (Book)context.getBean("book", Book.class);
System.out.println(book);
}
⑨ 提取公共bean
我们如果不想重复创建bean 想要单纯地提取出bean,然后多次引用就需要在协议 声明中 写上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: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.xsd ">
<!--提取公共bean-->
<util:list id="bookList">
<value>sd</value>
<value>dddd</value>
</util:list>
<bean id="book" class="com.xyq.spring_1.TestDemo.collectionBean.Book">
<property name="list" ref="bookList"></property>
</bean>
</beans>
我们可以发现util的声明其实是
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
将其beans都改成util既可以
⑩ 工厂bean
可以分出两种bean 一种是基本bean ,另一种是实现了FactoryBean<>接口的工厂bean
工厂bean有getObject() getObjectType() isSingleton() 三个抽象实现方法
意味着可以在工厂bean写上反射机制或者new来返回其他类 的bean (不是工厂类的bean)
有myBean类
public class myBean implements FactoryBean<Course> {
public myBean() {
}
public Course getObject() throws Exception {
Course course = new Course();
course.setcName("dsadas");
return course;
}
public Class<?> getObjectType() {
return Course.class;
}
public boolean isSingleton() {
return false;
}
}
xml文件
<bean id="myBean" class="com.xyq.spring_1.TestDemo.FactoryBean.myBean"></bean>
@Test
public void test02() {
ApplicationContext context = new ClassPathXmlApplicationContext("bean3.xml");
Course course = (Course)context.getBean("myBean", Course.class);
System.out.println(course);
}