加载Spring容器的三种方式

类路径获取配置文件(常用)
文件系统路径获得配置文件
使用BeanFactory(过时)

@Test
public void method01(){
//Sprin容器加载有三种方式
//第一种ClassPathXmlApplicationContext 类路径加载 ClassPath指的是classes路径
ApplicationContext context =new ClassPathXmlApplicationContext("beans.xml");
IUserService userService = (UserServiceImpl)context.getBean("userService");
userService.add();

//第二种方式:通过文件系统路径获取配置文件
ApplicationContext context1=new FileSystemXmlApplicationContext("D:\\JetBrains_2020\\SpringProject\\Spring01\\src\\beans.xml");
IUserService userService1 = (UserServiceImpl)context1.getBean("userService");
userService.add();

//第三种方式 使用BeanFactory
String path="D:\\JetBrains_2020\\SpringProject\\Spring01\\src\\beans.xml";
BeanFactory factory=new XmlBeanFactory(new FileSystemResource(path));
IUserService userService2 = (UserServiceImpl)factory.getBean("userService");
userService2.add();
}

ApplicationContext和BeanFactory的区别:

BeanFactory采用延迟加载,第一次getBean时才会初始化Bean
ApplicationContext是对BeanFactory扩展,提供了更多功能(国际化处理 事件传递 Bean自动装配 各种不同应用层的Context实现)

装配Bean

实例化Bean三种方式

<?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">
+
<!-- 第一种 new 实现类-->
<bean id="userService01" class="org.ccit.com.service.UserServiceImpl"></bean>
<!-- 第二种 通过静态工厂方法 编写工厂方法 返回一个实现类对象 这种方式不能使用Spring版本太低-->
<bean id="factory01" class="org.ccit.com.service.UserServiceFactory01" factory-method="creatUserService"></bean>
<!-- 第三种 通过实例工厂方法 将工厂类和实现类都配置(在实现类配置factory-bean factory-method) 在java代码中使用实现类的id -->
<bean id="factory02" class="org.ccit.com.service.UserServiceFactory02"></bean>
<bean id="userService03" factory-bean="factory02" factory-method="creatUserService"></bean>
</beans>

使用new实现类

public class Test04_zhuangpeiBean {
@Test
public void method01(){
ApplicationContext context=new ClassPathXmlApplicationContext("Beans3.xml");
//new 对象
IUserService userService01 = (IUserService)context.getBean("userService01");
userService01.add();
}
}

使用静态

public class Test04_zhuangpeiBean {
@Test
public void method01(){
ApplicationContext context=new ClassPathXmlApplicationContext("Beans3.xml");
//静态工厂
IUserService iUserService02 = (IUserService)context.getBean("factory01");
iUserService02.add();
}
}

实例工厂

public class Test04_zhuangpeiBean {
@Test
public void method01(){
ApplicationContext context=new ClassPathXmlApplicationContext("Beans3.xml");
//实例工厂
IUserService userService03 = (IUserService)context.getBean("userService03");
userService03.add();
}
}

Bean的作用域

singleton:在Spring IoC容器中仅存在一个Bean实例,Bean以单例方式存在 默认值
prototype:每次从容器中调用Bean时,都返回一个新的实例
request:每次http请求都会创建一个新的Bean 该作用域使用于WebApplicationContex环境
session:Session共享一个Bean 不同Seeion使用不同Bean,仅适用WebApplicationContext环境
globalSession:一般用于Protlet应用环境 该作用域仅适用于WebApplicationContext环境

<bean id="userService" class="org.ccit.com.service.UserServiceImpl" scope="prototype"></bean>
@Test
public void method(){
ApplicationContext context=new ClassPathXmlApplicationContext("Beans4.xml");
IUserService userService = (IUserService) context.getBean("userService");
System.out.println(userService);
IUserService userService1 = (IUserService) context.getBean("userService");
System.out.println(userService1);
}

Bean声明周期

<?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="user" class="org.ccit.com.model.User" init-method="myInit" destroy-method="myDestory">
<property name="username" value="张三"></property>
<property name="password" value="124"></property>
</bean>
<bean id="beanProcess" class="org.ccit.com.model.MyBeanPostprocessor"></bean>
</beans>
import org.ccit.com.model.User;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;


/**
* @program: Spring01
* @description
* @author: LIANG
* @create: 2021-04-03 16:56
**/
public class Test06_Bean_smzq {
//bean声明周期
/*
* 对象实例化:instantiate bean
* 封装属性: pipulate properties
* 如果Bean实现BeanNameAware执行setBeanName
* 如果Bean实现BeanFactoryAware执行setBeanFactory 获取Spring容器
* 如果存在类视频BeanPostProcessor(后处理Bean),执行postProcessBeforeInitializatioon
* 如果Bean实现InitializingBean执行afterPropertiesSet
* 调用<bean init-method="init">指定初始化方法init
* 如果存在类实现BeanPostProcessor(处理Bean) 执行postProcessAfterInitialization 执行处理业务
* 如果Bean实现DisposableBean 执行destroy
* 调用<bean destroy-method="customerDestroy">指定销毁方法 customerDestory*/


@Test
public void method01() throws Exception{
ApplicationContext context=new ClassPathXmlApplicationContext("Beans5.xml");
User user = (User)context.getBean("user");
System.out.println(user);
//关闭容器
context.getClass().getMethod("close").invoke(context);
}

}
package org.ccit.com.model;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;

/**
* @program: Spring01
* @description
* @author: LIANG
* @create: 2021-04-03 17:13
**/
public class User implements BeanNameAware, BeanFactoryAware, InitializingBean, DisposableBean {
private String username;
private String password;

public String getUsername() {
return username;
}

public void setUsername(String username) {
System.out.println("2,赋值属性"+username);
this.username = username;
}

public String getPassword() {
return password;
}

public void setPassword(String password) {
System.out.println("2,赋值属性"+password);
this.password = password;
}

public User() {
System.out.println("1,对象实例化");
}

@Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
", password='" + password + '\'' +
'}';
}

@Override
public void setBeanName(String s) {
System.out.println("3,设置Bean的名字"+s);
}

@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
//把对象放进工厂(容器)
System.out.println("4,将对象放入Bean工厂:"+beanFactory);
}

@Override
public void afterPropertiesSet() throws Exception {
System.out.println("6,属性赋值完成");
}

public void myInit(){
//资源释放
//自定义的初始化方法
System.out.println("7,自定义的初始化方法");
}
public void myDestory(){
//资源释放
//自定义的销毁方法
System.out.println("10,自定义销毁方法");
}
@Override
public void destroy() throws Exception {
System.out.println("9,bean销毁");
}

}
package org.ccit.com.model;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

/**
* @program: Spring01
* @description
* @author: LIANG
* @create: 2021-04-03 17:43
**/
public class MyBeanPostprocessor implements BeanPostProcessor {
//如果对许多对象进行相同的操作 使用该方法 对所有对象有效
@Override
public Object postProcessBeforeInitialization(Object bean, String beanname) throws BeansException {
System.out.println("5,预处理"+bean+" "+beanname);
return bean;
}

@Override
public Object postProcessAfterInitialization(Object bean, String beanname) throws BeansException {
System.out.println("8,后处理"+bean+" "+beanname);
return bean;
}
}

1,对象实例化
2,赋值属性张三
2,赋值属性124
3,设置Bean的名字user
4,将对象放入Bean工厂:org.springframework.beans.factory.support.DefaultListableBeanFactory@52719fb6: defining beans [user,beanProcess]; root of factory hierarchy
5,预处理User{username=‘张三’, password=‘124’} user
6,属性赋值完成
7,自定义的初始化方法
8,后处理User{username=‘张三’, password=‘124’} user
User{username=‘张三’, password=‘124’}
9,bean销毁
10,自定义销毁方法

依赖注入Bean属性

构造方法注入(根据给定的参数选择相应的构造方法)
属性setter方法注入
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">

<!-- 构造方法注入属性的值 根据参数自动调用相应的构造方法-->
<bean id="student" class="org.ccit.com.model.Student">
<constructor-arg name="username" value="张三"></constructor-arg>
<constructor-arg name="password" value="123"></constructor-arg>
</bean>
<!-- 也可以通过索引 和类型 帮助判别
<bean id="student" class="org.ccit.com.model.Student">
<constructor-arg index="0" value="张三" type="java.lang.String"></constructor-arg>
<constructor-arg index="1" value="123" type="java.lang.Integer"></constructor-arg>
</bean>
-->
<bean id="student" class="org.ccit.com.model.Student">
<constructor-arg name="username" value="张三"></constructor-arg>
<constructor-arg name="age" value="20"></constructor-arg>
</bean>
<!-- 通过setter方法注入-->
<bean id="Student" class="org.ccit.com.model.Student">
<property name="username" value="张三"></property>
<property name="password" value="123"></property>
</bean>

<!-- 通过p命名空间注入 需要提供set方法-->
<bean id="stu" class="org.ccit.com.model.Student" p:username="张三" p:password="123" p:age="12"></bean>
</beans>