4、注入属性-级联赋值
-
第一种写法
<!-- 级联赋值 --> <bean id="employees" class="spring5.bean.Employees"> <!--设置两个普通属性 --> <property name="ename" value="lucy"></property> <property name="gender" value="女"></property> <!--设置对象类型属性 --> <property name="department" ref="department"></property> </bean> <bean id="department" class="spring5.bean.Department"> <property name="dname" value="财务部"></property> </bean>
-
第二种写法
<bean id="employees" class="spring5.bean.Employees"> <property name="ename" value="lucy"></property> <property name="gender" value="女"></property> <property name="department.dname" value="技术部"></property> </bean>
此种写法设置对象类型属性具有get方法
public Department getDepartment() { return department; }
5、注入属性-集合属性
- 注入数组类型、List集合类型属性、Map类型属性、Set类型属性
- 创建类,定义这些类型的属性,生成对应set方法
package spring5.collectiontype;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class Student {
// 1.数组类型属性
private String[] courses;
// 2.list集合类型属性
private List<String> list;
// 3.map集合类型属性
private Map<String,String> map;
// 4.set集合类型属性
private Set<String> 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;
}
public void setSet(Set<String> set) {
this.set = set;
}
public void testStudent(){
System.out.println(Arrays.toString(courses));
System.out.println(list);
System.out.println(map);
System.out.println(set);
}
}
- 配置Spring文件
<bean id="student" class="spring5.collectiontype.Student">
<property name="courses">
<array>
<value>金融计量学</value>
<value>金融工程学</value>
</array>
</property>
<property name="list">
<list>
<value>张三</value>
<value>王六</value>
</list>
</property>
<property name="map">
<map>
<entry key="A" value="a"></entry>
<entry key="B" value="b"></entry>
</map>
</property>
<property name="set">
<set>
<value>C</value>
<value>D</value>
</set>
</property>
</bean>
测试类
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import spring5.collectiontype.Student;
public class TestCollectionType {
public static void main(String[] args) {
TestCollectionType tct = new TestCollectionType();
tct.test();
}
public void test(){
ApplicationContext ac = new ClassPathXmlApplicationContext("spring5\\bean4.xml");
Student student = ac.getBean("student", Student.class);
student.testStudent();
}
}
测试结果
[金融计量学, 金融工程学]
[张三, 王六]
{A=a, B=b}
[C, D]
3、集合里面设置对象类型的值
<property name="courseList">
<list>
<ref bean="course1"></ref>
<ref bean="course2"></ref>
</list>
</property>
<bean id="course1" class="spring5.collectiontype.Course">
<property name="cname" value="大话设计模式"></property>
</bean>
<bean id="course2" class="spring5.collectiontype.Course">
<property name="cname" value="大话数据结构"></property>
</bean>
//在Student类里面加了Course类型集合属性
private List<Course> courseList;//Course类型属性
public void setCourseList(List<Course> courseList) {
this.courseList = courseList;
}
//Course类
public class Course {
private String cname;//课程名称
public void setCname(String cname) {
this.cname = cname;
}
@Override
public String toString() {
return "Course{" +
"cname='" + cname + '\'' +
'}';
}
}
4、把集合注入部分提取出来
- 在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:xsi="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">
</beans>
2.使用util标签完成list集合注入提取
<?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">
<!--1 提取list集合类型属性注入-->
<util:list id="bookList">
<value>易筋经</value>
<value>九阴真经</value>
<value>九阳神功</value>
</util:list>
<!--2 提取list集合类型属性注入使用-->
<bean id="book" class="com.atguigu.spring5.collectiontype.Book" scope="prototype">
<property name="list" ref="bookList"></property>
</bean>
</beans>
Book类
import java.util.List;
public class Book {
private List<String> list;
public void setList(List<String> list) {
this.list = list;
}
}
IOC操作Bean管理(FactoryBean)
1、Spring有两种类型bean,一种普通的bean,另外一种工厂bean(FactoryBean)
2、普通bean:在配置文件中定义bean类型就是返回类型
3、工厂bean:在配置文件中定义bean类型可以和返回类型不一样
第一步 创建类,让这个类作为工厂bean,实现接口Factory
第二部 实现接口里面的方法,在实现的方法定义返回的bean类型
import org.springframework.beans.factory.FactoryBean;
import spring5.collectiontype.Course;
// 工厂Bean
public class MyBean implements FactoryBean<Course> {
@Override
public Course getObject() throws Exception {
Course course = new Course();
course.setCname("a");
return course;
}
@Override
public Class<?> getObjectType() {
return null;
}
}
<!--配置文件 -->
<?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="myBean" class="spring5.factorybean.MyBean"></bean>
</beans>
/**
*测试类
*/
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import spring5.collectiontype.Course;
public class TestFactoryBean {
public static void main(String[] args) {
TestFactoryBean testFactoryBean = new TestFactoryBean();
testFactoryBean.testFactoryBean();
}
public void testFactoryBean(){
ApplicationContext ac = new ClassPathXmlApplicationContext("spring5\\bean5.xml");
Course course = ac.getBean("myBean", Course.class);
System.out.println(course);
}
}
测试结果
Course{cname=‘a’}
IOC操作Bean管理(bean作用域)
1、在Spring里面,设置创建bean实例是单实例还是多实例
2、在Spring里面,默认情况下,bean是单实例对象
3、如何设置单实例还是多实例
- 在spring配置文件bean标签里面有属性(scope)用于设置单实例还是多实例
- scope属性值
第一个值 默认值 singleton,表示是单实例对象
第二个值 prototype,表示是多实例对象
- singleton和prototype区别
第一 singleton单实例,prototype多实例
第二 设置scope值是singleton时候,加载spring配置文件时候就会创建单实例对象
设置scope值是prototype时候,不是在加载spring配置文件时候创建对象,在调用getBean方法时候创建多实例对象
IOC操作Bean管理(Bean的生命周期)
-
生命周期
从对象创建到对象销毁过程
-
bean的生命周期
- 通过构造器创建bean的实例(无参数构造)
- 为bean的属性设置值和对其他bean引用(调用set方法)
- 把bean实例传递bean后置处理器的postProcessBeforeInitialization()方法
- 调用bean的初始化方法(需要进行配置初始化方法)
- 把bean实例传递bean后置处理器的postProcessAfterInitialization()方法
- bean可以使用了
- 当容器关闭时,调用bean的销毁方法(需要进行配置销毁方法)
private String oname; public Orders() { System.out.println("执行无参数构造方法创建bean实例"); } public void setOname(String oname) { this.oname = oname; System.out.println("为bean的属性设置值和对其他bean引用(调用set)"); } // 初始化方法 public void initMethod(){ System.out.println("执行初始化方法"); } // 销毁后方法 public void destoryMethod(){ System.out.println("执行销毁方法"); } }
bean后置处理器 让其实现BeanPostProcessor 接口类 两个方法
import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; /** * bean 的后置处理器 */ public class MyBeanPostProcessor implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("把bean实例传递bean后置处理器的方法postProcessBeforeInitialization"); return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("把bean实例传递bean后置处理器的方法postProcessAfterInitialization"); return bean; } }
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"> <!-- init-method 初始化方法 destory-method 销毁后方法--> <bean id="orders" class="spring5.bean.Orders" init-method="initMethod" destroy-method="destoryMethod"> <property name="oname" value="iphone12"></property> </bean> <!-- 配置后置处理器 后置处理器将会对以上所有bean进行配置 --> <bean id="myBeanPostProcessor" class="spring5.bean.MyBeanPostProcessor"> </bean> </beans>
测试类
import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import spring5.bean.Orders; /** * 测试bean生命周期 */ public class TestBeanLifeCycle { public static void main(String[] args) { TestBeanLifeCycle t = new TestBeanLifeCycle(); t.testBeanLifeCycle(); } // 测试bean生命周期 public void testBeanLifeCycle(){ ApplicationContext ac = new ClassPathXmlApplicationContext("spring5\\bean6.xml"); Orders orders = ac.getBean("orders", Orders.class); System.out.println(orders); //关闭容器 ((ClassPathXmlApplicationContext)ac).close(); } }
测试结果
执行无参数构造方法创建bean实例 为bean的属性设置值和对其他bean引用(调用set) 把bean实例传递bean后置处理器的方法postProcessBeforeInitialization 执行初始化方法 把bean实例传递bean后置处理器的方法postProcessAfterInitialization spring5.bean.Orders@1e127982 执行销毁方法
IOC操作Bean管理(基于注解方式)
1、注解
- 格式:@注解名称(属性名称=属性值,属性名称=属性值…)
- 使用注解,注解在类上面,方法上面,属性上面。
- 使用注解目的:简化XML配置
2、Spring针对Bean管理中创建对象提供的注解
- @Component
- @Service
- @Controller
- @Repository
上面四个注解功能是一样的,都可以用来创建bean实例
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: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"> <!-- 如果扫描多个包,多个包使用逗号隔开 扫描包上层目录--> <context:component-scan base-package="spring5.annotation"></context:component-scan> </beans>
第三步 创建类,在类上面添加创建对象注解
@Component 默认值是类名称,首字母小写
- eg:UserService --> userService
- @Component(value = “userService”)
- 等价于
import org.springframework.stereotype.Component; @Component public class UserService { public void add(){ System.out.println("userservice add...."); } }
4、开启组件扫描细节配置
<?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"> <!-- 示例1 --> <!-- include-filter 设置扫描那些内容 type类型 expression 表达式 --> <context:component-scan base-package="spring5.annotation" use-default-filters="false"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan> <!-- 示例2 --> <!-- exclude-filter 设置不扫描哪些内容,别的内容扫描--> <context:component-scan base-package="spring5.annotation"> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan> </beans>
5、基于注解方式实现属性注入
-
@Autowired:根据属性类型进行自动装配
//定义UserDao类型属性 //不需要添加set方法 @Autowired private UserDao userDao1;
-
@Qualifier:根据名称进行注入 一定要和@Autowired一块使用
@Autowired @Qualifier(value = "userDaoImpl") private UserDao userDao;
-
@Resource:可以根据类型注入,也可以根据名称注入。
//根据类型注入 @Resource private UserDao userDao2;
//根据名称注入 @Resource(name = "userDaoImpl") private UserDao userDao3;
-
注入普通类型属性
@Value("abc") private String name;
-
-
6、完全注解开发
-
创建配置类,替代xml配置文件
import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; /** * 配置类 * 完全注解开发 */ @Configuration @ComponentScan(basePackages = {"spring5.annotation"}) public class MySpringConfig { }
其他类 为了测试结果
public interface UserDao { public void add(); }
import org.springframework.stereotype.Repository; @Repository public class UserDaoImpl implements UserDao{ @Override public void add() { System.out.println("userdao add ...."); } }
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import javax.annotation.Resource; @Component public class UserService { @Autowired @Qualifier(value = "userDaoImpl") private UserDao userDao; @Autowired private UserDao userDao1; @Resource private UserDao userDao2; @Resource(name = "userDaoImpl") private UserDao userDao3; @Value("abc") private String name; public void add(){ userDao.add(); userDao1.add(); userDao2.add(); userDao3.add(); } public UserService() { } }
测试类
public class TestAnnotation { // 重点是new AnnotationConfigApplicationContext(); @Test public void test1(){ ApplicationContext ac = new AnnotationConfigApplicationContext(MySpringConfig.class); UserService us = ac.getBean("userService", UserService.class); System.out.println(us); us.add(); } }
测试结果
spring5.annotation.UserService@647fd8ce userdao add .... userdao add .... userdao add .... userdao add ....