由于 id 属性指定了 bean 的唯一标识,所以根据 bean 标签的 id 属性可以精确获取到一个组件对象。
package com.gothic.sunset.demo;public class HelloWorld {public void sayHello(){System.out.println("HelloWorld!");}
}
applicationContext:
测试代码:
@Testpublic void testHello(){ApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext.xml");//通过bean标签的id值来获取beanHelloWorld helloWorld = (HelloWorld)ioc.getBean("HelloWorld");helloWorld.sayHello();//输出HelloWorld!}
这里通过观察package org.springframework.beans.factory;
,BeanFactory接口为我们提供了多种获取bean的方式。
还是使用上面的helloworld的例子:
@Testpublic void testHello(){ApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext.xml");//通过bean标签的id值来获取bean/*HelloWorld helloWorld = (HelloWorld)ioc.getBean("HelloWorld");*///通过class属性来获取BeanHelloWorld helloWorld = ioc.getBean(HelloWorld.class);helloWorld.sayHello();}
@Testpublic void testHello(){ApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext.xml");//1.通过bean标签的id值来获取bean/*HelloWorld helloWorld = (HelloWorld)ioc.getBean("HelloWorld");*///2.通过class属性来获取Bean/*HelloWorld helloWorld = ioc.getBean(HelloWorld.class);*/HelloWorld helloWorld = ioc.getBean("HelloWorld", HelloWorld.class);helloWorld.sayHello();}
首先创建一个实体类Student,用于例子测试:
package com.gothic.sunset.demo;public class Student {private Integer id;//学生idprivate String name;//学生姓名private String sex;//学生性别private Integer age;//学生年龄public Student() {}public Integer getId() {return id;}public Student(Integer id, String name, String sex, Integer age) {this.id = id;this.name = name;this.sex = sex;this.age = age;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getSex() {return sex;}public void setSex(String sex) {this.sex = sex;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}@Overridepublic String toString() {return "Student{" +"id=" + id +", name='" + name + '\'' +", sex='" + sex + '\'' +", age=" + age +'}';}
}
然后通过bean标签的property子标签,配置bean时为属性赋值:
property标签中需要注意的是,value属性值为字面量,你可以思考一下,上面我们规定年龄和id为Integer类型。
测试输出:
@Testpublic void testSetterBean(){ApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext.xml");Student studentSetter = (Student)ioc.getBean("StudentSetter");System.out.println(studentSetter);}
有参构造器注入,必须在对应实体类中有有参构造器。然后有参构造注入是用到了constructor-arg
标签:
测试输出:
@Testpublic void testConstructorBean(){ApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext.xml");Student student = (Student)ioc.getBean("StudentConstructor");System.out.println(student);}
前面已经说过property标签中的value属性值填写的是字面量。
比如上面我们的setter注入和构造器注入中的id,age这两个属性,它们最后都是数字。
注入bean时,我们常常想要一些属性一开始为空。这里大家可以想一下如果只是在property标签的value属性中填写null值是否会成功?
先来测试一下,在property标签的value属性中填写null值:
测试输出:
@Testpublic void testBeanNull(){ApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext.xml");Student student = (Student)ioc.getBean("StudentDemo1Null");System.out.println(student);System.out.println(null==student.getSex());}
由此可见,value将null作为了字符串null。
其实我们可以用null标签,对上面的代码修改如下:
测试输出:
一些时候,我们想为一些属性值插入一些符号,比如>,<…这样,首先,我们基于xml管理bean和手动注入是在xml中进行的,所以这些大于小于号,是无法直接像上面那样插入到属性中的。
学过前端的,都应该知道xml实体是什么,所以我们可以之间通过xml实体来插入这些特殊的大于小于号:
< >
分别代表大于小于号。
CDATA节也是为了解决上面xml实体的问题:
为类类属性赋值,类似我们之前的mybatis中的一对多和多对一。
一个班级有多个学生,每个学生只有一个班级。
首先我们创建一个班级实体类:
package com.gothic.sunset.demo;public class ClassSt {private Integer classStId;//班级号private String classStName;//班级名称public Integer getClassStId() {return classStId;}public void setClassStId(Integer classStId) {this.classStId = classStId;}public String getClassStName() {return classStName;}public void setClassStName(String classStName) {this.classStName = classStName;}@Overridepublic String toString() {return "ClassSt{" +"classStId=" + classStId +", classStName='" + classStName + '\'' +'}';}
}
然后修改之前的学生类,在其中添加班级属性:
package com.gothic.sunset.demo;public class Student {private Integer id;private String name;private String sex;private Integer age;/*新增classSt属性,并为其提供setter和getter方法,以及重写toString方法*/private ClassSt classSt;public ClassSt getClassSt() {return classSt;}public void setClassSt(ClassSt classSt) {this.classSt = classSt;}public Student() {}public Integer getId() {return id;}public Student(Integer id, String name, String sex, Integer age) {this.id = id;this.name = name;this.sex = sex;this.age = age;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getSex() {return sex;}public void setSex(String sex) {this.sex = sex;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}@Overridepublic String toString() {return "Student{" +"id=" + id +", name='" + name + '\'' +", sex='" + sex + '\'' +", age=" + age +", classSt=" + classSt +'}';}
}
这里我们可以使用ref标签来引入外部已经声明的bean:
测试输出:
@Testpublic void testClassStBean(){ApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext.xml");Student student = (Student)ioc.getBean("studentOne");System.out.println(student);}
内部bean的方式即在内部再嵌入一个bean标签:
在一个bean中再声明一个bean就是内部bean,内部bean只能用于给属性赋值,不能在外部通过IOC容器获取,因此可以省略id属性。
测试输出:
@Testpublic void testClassStBean2(){ApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext.xml");Student student = (Student)ioc.getBean("studentTwo");System.out.println(student);}
级联属性赋值与mybatis中的级联处理,如出一辙:
这里需要注意的是,一定先引用某个bean为属性赋值,才可以使用级联方式更新属性。
输出:
面向不同的问题,spring为我们提供了不同的标签注入。
在学生类中新增一项爱好属性,一个学生的爱好有好多种,所以为一个数组。
package com.gothic.sunset.demo;public class Student {//......//新增爱好属性,添加get set 然后重写toString方法private String[] hobbies;public String[] getHobbies() {return hobbies;}public void setHobbies(String[] hobbies) {this.hobbies = hobbies;}}
使用array标签为bean注入属性值:
绘画 唱歌 跑步
测试输出:
@Testpublic void testClassStBean(){ApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext.xml");//Student student = (Student)ioc.getBean("studentOne");//Student student = (Student)ioc.getBean("studentThree");Student student = (Student)ioc.getBean("studentFour");System.out.println(student);}
一个班级有多个学生,一对多,为班级类添加一个学生集合:
package com.gothic.sunset.demo;import java.util.List;public class ClassSt {//新增学生集合属性private List students;public List getStudents() {return students;}public void setStudents(List students) {this.students = students;}}
使用list标签,将多个学生注入bean中:
测试输出:
@Testpublic void testClassStBean2(){ApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext.xml");ClassSt classSt = (ClassSt)ioc.getBean("studentList");System.out.println(classSt);}
学生选修多门课程,不同的课程号对应不同的老师,使用Map的key,value映射注入bean。
首先创建教师类:
package com.gothic.sunset.demo;public class Teacher {private Integer teacherId;private String teacherName;public Integer getTeacherId() {return teacherId;}public void setTeacherId(Integer teacherId) {this.teacherId = teacherId;}public String getTeacherName() {return teacherName;}public void setTeacherName(String teacherName) {this.teacherName = teacherName;}@Overridepublic String toString() {return "Teacher{" +"teacherId=" + teacherId +", teacherName='" + teacherName + '\'' +'}';}
}
在学生中添加对应的老师属性:
package com.gothic.sunset.demo;import java.util.Arrays;
import java.util.Map;public class Student {//......//新增private Map teacherMap;public Map getTeacherMap() {return teacherMap;}public void setTeacherMap(Map teacherMap) {this.teacherMap = teacherMap;}
}
使用map标签注入bean:
跑步 武术 足球
测试输出:
@Testpublic void testClassStBean(){ApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext.xml");//Student student = (Student)ioc.getBean("studentOne");//Student student = (Student)ioc.getBean("studentThree");// Student student = (Student)ioc.getBean("studentTwo");// Student student = (Student)ioc.getBean("studentFour");Student student = (Student)ioc.getBean("studentFive");System.out.println(student);}
until标签的作用就是,可以将一些类型的bean作为一个整体,供其他bean方便引用。
首先,需要在spring配置文件的头部添加xmlns:util="http://www.springframework.org/schema/util"
,idea一般会自动导入。
然后就可以开始写until标签的一些集合:
88 99
注意的是,与上面的util一样,也需要在spring配置文件的头部中添加xmlns:p="http://www.springframework.org/schema/p"
引入p命名空间后,可以通过以下方式为bean的各个属性赋值:
在Spring中可以通过配置bean标签的scope属性来指定bean的作用域范围:
在WebApplicationContext环境下还会有另外两个作用域:
具体的生命周期过程:
配置bean:
在bean标签的配置中,可以使用init-method和destroy-method属性,分别指定初始化和销毁方法。
....
后置处理器:
bean的后置处理器会在生命周期的初始化前后添加额外的操作,需要实现BeanPostProcessor接口,
且配置到IOC容器中,需要注意的是,bean后置处理器不是单独针对某一个bean生效,而是针对IOC容
器中所有bean都会执行。
创建bean的后置处理器:
package com.gothic.sunset.demo;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
public class MyTestBeanProcessor implements BeanPostProcessor {@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName)throws BeansException {System.out.println("lalala" + beanName + " = " + bean);return bean;}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName)throws BeansException {System.out.println("dadada" + beanName + " = " + bean);return bean;}
}
在IOC容器中配置后置处理器:
自动装配:
根据指定的策略,在IOC容器中匹配某一个bean,自动为指定的bean中所依赖的类类型或接口类型属性赋值。
使用bean标签的autowire属性设置自动装配效果,autuwire=byType|byName
。
byType:根据类型匹配IOC容器中的某个兼容类型的bean,为属性自动赋值
若在IOC中,没有任何一个兼容类型的bean能够为属性赋值,则该属性不装配,即值为默认值null。
若在IOC中,有多个兼容类型的bean能够为属性赋值,则抛出异常NoUniqueBeanDefinitionException。
byName:将自动装配的属性的属性名,作为bean的id在IOC容器中匹配相对应的bean进行赋值
项目目录结构:
1.dao层:
dao层接口:
package com.gothic.sunset.autowire.dao;public interface UserDao {void saveUser();
}
dao层实现类:
package com.gothic.sunset.autowire.dao;public class UserDaoImpl implements UserDao{@Overridepublic void saveUser() {System.out.println("ok,保存成功啦!!!");}
}
2.service层:
service层接口:
package com.gothic.sunset.autowire.service;public interface UserService {void saveUser();
}
service层实现类:
package com.gothic.sunset.autowire.service;import com.gothic.sunset.autowire.dao.UserDaoImpl;public class UserServiceImpl implements UserService{private UserDaoImpl userDao;public UserDaoImpl getUserDao() {return userDao;}public void setUserDao(UserDaoImpl userDao) {this.userDao = userDao;}@Overridepublic void saveUser() {userDao.saveUser();}
}
3.controller层:
controller层实现类:
package com.gothic.sunset.autowire.controller;import com.gothic.sunset.autowire.service.UserServiceImpl;public class UserController {private UserServiceImpl userService;public UserServiceImpl getUserService() {return userService;}public void setUserService(UserServiceImpl userService) {this.userService = userService;}public void saveUser(){userService.saveUser();}
}
4.配置bean
在resources目录下新建一个,名为springAutoWireTest.xml,的spring配置文件:
5.测试代码:
import com.gothic.sunset.autowire.controller.UserController;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class MyTestAutoWire {@Testpublic void testAutoWire(){ApplicationContext ioc = new ClassPathXmlApplicationContext("springAutoWireTest.xml");UserController bean = ioc.getBean(UserController.class);bean.saveUser();}
}
输出:
byName方式就不演示啦,xml配置管理bean暂告一段落!!!!
上一篇:CSRF漏洞简介