1. 什么是Bean管理
使用spring创建对象
使用spring注入属性
2. Bean的管理有两种方式
1. 基于XML方式配置
基于XML方式创建对象
在spring的配置文件中,会配置一个bean标签,注入bean的信息 创建bean对象
Id:获取bean对象 唯一bean对象的名称; bean的名称不允许重复
Class属性: 类的完整路径地址(类名称+包名称)
默认底层使用反射技术执行无参数构造函数
2. 基于xml方式注入属性
DI 依赖注入: 对象的属性注入值; (spring实现)
1. 第一种实现方式:基于对象属性set方法实现
在Bean标签下 在定义一个属性标签
Name:类中的属性名称
Value:需要注入属性值
实例类
public class OrderEntity {
private String orderId;
private String orderName;
public OrderEntity(String orderId, String orderName) {
this.orderId = orderId;
this.orderName = orderName;
}
@Override
public String toString() {
return "OrderEntity{" +
"orderId='" + orderId + '\'' +
", orderName='" + orderName + '\'' +
'}';
}
}
Xml配置文件
<constructor-arg index 指定参数列表索引
1. Xml头部引入P标签
2. 使用p标签注入属性:
使用p标签为属性注入值:调用set方法注入值
注入空值属性
注入特殊符号
转移注入方式
<< 转移为:<<
>>转移为:>>
Cdata注入方式
>]]>
>]]>
Com.mayikt.controller---控制层
Com.mayikt.service----业务逻辑层
MemberService ##new MemberDao().
Com.mayikt.dao----数据库访问层
MemberDao----
Com.mayikt.service
调用:memberService
Com.mayikt.dao
MemberDaoImpl
public interface MemberDao {
void addMember();
}
public class MemberDaoImpl implements MemberDao {
public void addMember() {
System.out.println("dao member");
}
}
import com.mayikt.dao.MemberDao;
import com.mayikt.dao.MemberDaoImpl;
public class MemberService {
private MemberDao memberDao;
public MemberDao getMemberDao() {
return memberDao;
}
public void setMemberDao(MemberDao memberDao) {
this.memberDao = memberDao;
}
public void addMember() {
System.out.println("<<>");
// 原始的方式
// MemberDao memberDao = new MemberDaoImpl();
// memberDao.addMember();
memberDao.addMember();
}
}
1. 数据库表一对多或者一对一的关系
2. 部门--n多个员工 一对多
3. 站在员工角度考虑员工属于那个部门
4. 站在部门的角度考虑部门下n多个员工
1. 在数据库中表中有一对一一对多的关系;
2. 一对多关系;部门与员工 一个部门会有多个员工 一个员工属于一个部门;
3. 实体类之间表示一对多的关系;
实体类员工对象
public class EmpEntity {
private String name;
private Integer age;
/**
* 员工属于那个部门
*/
private DeptEntity deptEntity;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public void setDeptEntity(DeptEntity deptEntity) {
this.deptEntity = deptEntity;
}
@Override
public String toString() {
return "EmpEntity{" +
"name='" + name + '\'' +
", age=" + age +
", deptEntity=" + deptEntity +
'}';
}
}
部门对象
public class DeptEntity {
private String name;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
@Override
public String toString() {
return "DeptEntity{" +
"name='" + name + '\'' +
'}';
}
}
Xml相关配置
写法1
写法2
注意:需要在员工实体类新增:deptEntity get方法。
1. 注入数组类型
2. 注入list集合类型
3. 注入Map集合类型属性
4. 注入set集合属性
实体类
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class StuEntity {
//1.数组属性
private String[] arrays;
//2.list集合属性
private List list;
//3.Map
private Map map;
//4.Set
private Set set;
public void setArrays(String[] arrays) {
this.arrays = arrays;
}
public void setList(List list) {
this.list = list;
}
public void setMap(Map map) {
this.map = map;
}
public void setSet(Set set) {
this.set = set;
}
@Override
public String toString() {
return "StuEntity{" +
"arrays=" + Arrays.toString(arrays) +
", list=" + list +
", map=" + map +
", set=" + set +
'}';
}
}
配置文件
mayikt01
mayikt02
语文
数学
01
02
集合类型为对象
private List courses;
public void setCourses(List courses) {
this.courses = courses;
}
public class CourseEntity {
private String name;
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "CourseEntity{" +
"name='" + name + '\'' +
'}';
}
}
list01
list02
mayikt01
mayikt02
list01
list02
集合注入部分提取公共
1. 需要先引入一个util名称空间
2. 使用util标签 注入
mayikt01
mayikt02
1. Spring中两种类型bean,一种是为普通的bean,另外一种是工厂bean
FactoryBean
2. 普通Bean:在配置文件中定义什么类型与返回的类型需一致;
3. 工厂Bean:在配置文件中定义Bean类型与返回类型可以不一致;
创建一个类,这个类是为工厂Bean,实现FactoryBean接口
import com.mayikt.entity.UserEntity;
import org.springframework.beans.factory.FactoryBean;
public class MayiktBean implements FactoryBean {
/**
* 定义返回bean
*
* @return
* @throws Exception
*/
public UserEntity getObject() throws Exception {
return new UserEntity();
}
public Class> getObjectType() {
return null;
}
}
public static void main(String[] args) {
ClassPathXmlApplicationContext app =
new ClassPathXmlApplicationContext("spring_08.xml");
UserEntity mayiktBean = (UserEntity) app.getBean("mayiktBean");
System.out.println(mayiktBean);
}
什么是作用域?
设定bean作用域是为单例还是多例
作用域单例与多例有什么区别呢?
1. 单例的作用域:每次在调用getbean方法获取对象都是为同一个对象;
2. 多例的作用域:每次在调用getbean方法获取对象都是一个
新的对象。
注意:在spring默认的情况下,bean的作用域就是为单例 节约服务器内存。
单例:
在同一个jvm中,该bean对象只会创建一次。
多例:
在同一个jvm中,该bean对象可以被创建多次。
设定对象单例还是多例
在spring的默认的情况下,springbean的作用域为单例。
1.单例就是每次获取bean都是同一个对象;
2.多例就是每次获取bean都是新的一个对象;
单例:在同一个jvm中该bean只能存在一个实例;
多例子:在同一个jvm中该bean存在多个实例;
证明:如果是为单例,则两个对象地址都是一样的,
多例子对象则两个对象地址不一样。
单例配置:
默认就是为单例子;
多例配置:
简单分为:实例化→属性赋值→初始化→销毁
生命周期概念:
1. 对象的创建与销毁的过程,类似之前学习servlet生命的周期过程。
生命周期的原理:
1. 通过构造函数创建bean对象(默认执行无参构造函数 底层基于反射实现)
2. 为bean的属性设置 (使用反射调用set方法)
3. 调用bean的初始化的方法(需要单独在类中配置初始化的方法)
4. 正常使用bean对象
5. Spring容器关闭,调用该类的销毁回调的方法(需要单独在类中配置销毁的方法)
public class MemberEntity {
private String name;
public MemberEntity(){
System.out.println("[第一步]-无参构造函数被执行---反射机制调用");
}
public void setName(String name) {
System.out.println("[第二步]-set方法初始化属性---反射机制调用");
this.name = name;
}
/**
* 回调调用init初始化方法
*/
public void initMethod(){
System.out.println("[第三步]-回调调用init初始化方法");
}
/**
* destroyMethod
*/
public void destroyMethod(){
System.out.println("[第五步]-回调调用destroyMethod方法");
}
}
import com.mayikt.entity.MemberEntity;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test07 {
public static void main(String[] args) {
ClassPathXmlApplicationContext app =
new ClassPathXmlApplicationContext("spring_07.xml");
MemberEntity memberEntity= app.getBean("memberEntity",MemberEntity.class);
System.out.println("[第四步]-获取使用到的memberEntity");
System.out.println(memberEntity);
// 手动让bean容器销毁
app.close();
}
}
Bean的后置处理器 作用提供更多的扩展功能 BeanPostProcessor
相关演示代码
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
public class MayiktBeanPost implements BeanPostProcessor {
/**
* 调用初始化方法之前执行
* @param bean
* @param beanName
* @return
* @throws BeansException
*/
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("在bean 初始化方法之前执行");
return bean;
}
/**
* 调用初始化方法之后执行
* @param bean
* @param beanName
* @return
* @throws BeansException
*/
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("在bean 初始化方法之后执行");
return bean;
}
}
1.通过构造函数创建bean对象(默认执行无参构造函数 底层基于反射实现)
2.为bean的属性设置 (使用反射调用set方法)
3.将bean传递给后置处理器 调用初始化方法之前执行
4.调用bean的初始化的方法(需要单独在类中配置初始化的方法)
5.将bean传递给后置处理器 调用初始化方法之后执行
6.正常使用bean对象
7.Spring容器关闭,调用该类的销毁回调的方法(需要单独在类中配置销毁的方法)
后置处理器底层原理
配置多个BeanPostProcessor
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.core.Ordered;
public class MayiktBeanPost implements BeanPostProcessor, Ordered {
/**
* 调用初始化方法之前执行
* @param bean
* @param beanName
* @return
* @throws BeansException
*/
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("调用该bean的 init方法之前");
return bean;
}
/**
* 调用初始化方法之后执行
* @param bean
* @param beanName
* @return
* @throws BeansException
*/
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("调用该bean的 init方法之后");
return bean;
}
public int getOrder() {
return 1;
}
}
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.core.Ordered;
public class MayiktBeanPost02 implements BeanPostProcessor, Ordered {
/**
* 调用初始化方法之前执行
* @param bean
* @param beanName
* @return
* @throws BeansException
*/
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("[MayiktBeanPost02:]调用该bean的 init方法之前");
return bean;
}
/**
* 调用初始化方法之后执行
* @param bean
* @param beanName
* @return
* @throws BeansException
*/
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("[MayiktBeanPost02:]调用该bean的 init方法之后");
return bean;
}
public int getOrder() {
return 0;
}
}
实现Ordered接口 getOrder 值越小越优先加载
什么是自动装配呢
根据装配的规则(属性的名称或者属性的类型)
Spring根据装配的规则自动为属性注入值。
1. 什么是自动装配
A. 根据指定装配规则(属性名称或者属性的类型),spring自动将匹配属性的值注入。
Bean的管理操作方式
1. 基于XML方式实现
2. 基于注解方式实现
什么是注解:注解是JDK5中推出的新特性,代码的特殊标记,
格式注解名称“属性名称=属性值,属性名称=属性值”。
我们在后期学习springboot开发基本上都是使用注解,很少在使用
Xml配置的方式。
注解可以使用在类、方法、属性、上面。
使用注解的目的,简化xml的配置方式。
Spring提供的常用注解
1. @Component 将对象注入Spring容器中
2. @Service 注入业务逻辑对象
3. @Controller 控制器类
4. @Repository 注入dao对象
5. 以上该四个注解底层都是基于@Component注解封装的,只是区分用于
在不同的场景下。
注解的使用方式
AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext();
app.register(BeanConfig.class);
app.refresh();
MemberEntity memberEntity = (MemberEntity) app.getBean("memberEntity");
System.out.println(memberEntity);