Spring:IOC的原理和使用

您所在的位置:网站首页 spring的ioc的三种实现方式 Spring:IOC的原理和使用

Spring:IOC的原理和使用

#Spring:IOC的原理和使用| 来源: 网络整理| 查看: 265

一. IOC容器底层原理

本质上就是 对象工厂 + 反射

eg: 将xml解析得到dao类包路径,工厂模式factory通过反射用类名创建出对象返回,service类直接通过 factory调用userdao,进一步降低耦合 实际上,factory经过Spring的进一步优化就是IOC容器

截屏2023-02-10 16.55.18.png

二. IOC容器实现方式:两个接口

截屏2023-02-10 11.04.35.png 截屏2023-02-10 11.18.36.png

三. Ioc的bean管理 1.什么是bean管理

指Spring操作对象和Spring注入属性

2.操作方式 2.1 基于xml配置文件的方式

官网:尽管 XML 一直是定义配置元数据的传统格式,但你可以通过提供少量的 XML 配置来指示容器使用 Java 注释或代码作为元数据格式,从而声明性地支持这些附加的元数据格式。

2.1.1 创建对象 复制代码 2.1.2 基于set方法注入属性(DI:依赖注入) 创建类,定义属性和对应的set方法 public class Book { //创建属性 private String bname; //创建属性对应的set方法 public void setBname(String bname) { this.bname = bname; } } 复制代码 2.1.3 基于有参构造函数注入属性 (1)传统方式:创建类,构建有参函数 public class Orders { //属性 private String oname; private String address; //有参数构造 public Orders(String oname,String address) { this.oname = oname; this.address = address; } } 复制代码 2.1.4 基于p命名空间注入属性 > 复制代码 2.1.5 基于外部bean注入属性 public class UserService {//service类 //创建UserDao类型属性,生成set方法 private UserDao userDao; public void setUserDao(UserDao userDao) { this.userDao = userDao; } public void add() { System.out.println("service add..............."); userDao.update();//调用dao方法 } } public class UserDaoImpl implements UserDao {//dao类 @Override public void update() { System.out.println("dao update..........."); } } Spring XML 复制代码 2.1.6 基于内部bean注入属性 //部门类 public class Dept { private String dname; public void setDname(String dname) { this.dname = dname; } } //员工类 public class Emp { private String ename; private String gender; //员工属于某一个部门,使用对象形式表示 private Dept dept; public void setDept(Dept dept) { this.dept = dept; } public void setEname(String ename) { this.ename = ename; } public void setGender(String gender) { this.gender = gender; } } spring xml 复制代码 2.1.7 基于内部bean注入属性 - 级联赋值 复制代码 //方式二:生成dept的get方法(get方法必须有!!) public Dept getDept() { return dept; } 复制代码 2.1.8 注入集合属性

1、注入数组类型属性 2、注入 List 集合类型属性 3、注入 Map 集合类型属性

//(1)创建类,定义数组、list、map、set 类型属性,生成对应 set 方法 public class Stu { //1 数组类型属性 private String[] courses; //2 list集合类型属性 private List list; //3 map集合类型属性 private Map maps; //4 set集合类型属性 private Set sets; public void setSets(Set sets) { this.sets = sets; } public void setCourses(String[] courses) { this.courses = courses; } public void setList(List list) { this.list = list; } public void setMaps(Map maps) { this.maps = maps; } 复制代码 java课程 数据库课程 张三 小三 MySQL Redis 复制代码 2.1.9 注入属性时在集合里面设置对象类型的值 //学生所学多门课程 private List courseList;//创建集合 public void setCourseList(List courseList) { this.courseList = courseList; } 复制代码 复制代码 2.1.10 注入属性时 提取公共集合 > 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"> 易筋经 九阴真经 九阳神功 复制代码 2.1.11 注入属性时 自动装配

截屏2023-02-10 19.26.08.png

bytype要注意多个同type bean会报错

2.1.12 引入外部属性文件

创建外部属性文件,properties 格式文件,写数据库信息jdbc.properties

prop.driverClass=com.mysql.jdbc.Driver prop.url=jdbc:mysql://localhost:3306/userDb prop.userName=root prop.password=root 复制代码 复制代码 2.2 基于注解的方式 日常开发通常基于springboot实现 2.2.1 创建对象

​ 1.第一步 引入依赖 (引入spring-aop jar包) ​ 2.第二步 开启组件扫描 在xml文件引入context命名空间

复制代码

​ 3.第三步 创建类,在类上面添加创建对象注解

//在注解里面 value 属性值可以省略不写, //默认值是类名称,首字母小写 //UserService -- userService @Component(value = "userService") //注解等同于XML配置文件: public class UserService { public void add() { System.out.println("service add......."); } } 复制代码

​ 4、可选 开启组件扫描细节配置

复制代码 2.2.2 基于@Autowired注入属性

​ 1.@Autowired:根据属性类型进行自动装配 (1) 把 service 和 dao 对象创建,在 service 和 dao 类添加创建对象注解 (2)在 service 注入 dao 对象,在 service 类添加 dao 类型属性,在属性上面使用注解

@Service public class UserService { //定义 dao 类型属性 //不需要添加 set 方法 //添加注入属性注解 @Autowired private UserDao userDao; public void add() { System.out.println("service add......."); userDao.add(); } } //Dao实现类 @Repository //@Repository(value = "userDaoImpl1") public class UserDaoImpl implements UserDao { @Override public void add() { System.out.println("dao add....."); } } 复制代码 2.2.3 基于@Qualifier注入属性

​ @Qualifier:根据名称进行注入,这个@Qualifier 注解的使用,和上面@Autowired 一起使用

//定义 dao 类型属性 //不需要添加 set 方法 //添加注入属性注解 @Autowired //根据类型进行注入 //根据名称进行注入(目的在于区别同一接口下有多个实现类,只通过@autowire根据类型就无法选择,从而出错!) @Qualifier(value = "userDaoImpl1") private UserDao userDao; 复制代码 2.2.4 基于@Resource注入属性

​ @Resource:可以根据类型注入,也可以根据名称注入(它属于javax包下的注解,spring官方不推荐使用!)

//@Resource //根据类型进行注入 @Resource(name = "userDaoImpl1") //根据名称进行注入 private UserDao userDao; 复制代码 2.2.5 基于@Value注入属性 @Value(value = "abc") private String name 复制代码 3.完全注解开发 3.1 创建配置类,替代 xml 配置文件 @Configuration //作为配置类,替代 xml 配置文件 @ComponentScan(basePackages = {"com.atguigu"}) //替代xml的扫描路径 public class SpringConfig { } 复制代码 3.2 编写测试类 @Test public void testService2() { //加载配置类 ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class); UserService userService = context.getBean("userService", UserService.class); System.out.println(userService); userService.add(); } 复制代码 四.bean作用域

​ 在 Spring 里面,默认情况下,bean 是单实例对象,下面进行作用域设置:

(1)在 spring 配置文件 bean 标签里面有属性(scope)用于设置单实例还是多实例 (2)scope 属性值 第一个值 默认值,singleton,表示是单实例对象 第二个值 prototype,表示是多实例对象 (3)singleton 和 prototype 区别 ​ a)singleton 单实例,prototype 多实例 ​ b)设置 scope 值是 singleton 时候,加载 spring 配置文件时候就会创建单实例对象 ;设置 scope 值是 prototype 时候,不是在加载 spring 配置文件时候创建对象,在调用 getBean 方法时候创建多实例对象 复制代码 五.bean生命周期 5.1 什么是生命周期

从对象创建到对象销毁的过程

5.2 bean 生命周期 ​ (1)通过构造器创建 bean 实例(无参数构造) ​ (2)为 bean 的属性设置值和对其他 bean 引用(调用 set 方法) ​ (3)把 bean 实例传递 bean 后置处理器的方法 postProcessBeforeInitialization ​ (4)调用 bean 的初始化的方法(需要进行配置初始化的方法) ​ (5)把 bean 实例传递 bean 后置处理器的方法 postProcessAfterInitialization ​ (6)bean 可以使用了(对象获取到了) ​ (7)当容器关闭时候,调用 bean 的销毁的方法(需要进行配置销毁的方法) 复制代码 5.3 演示 bean 生命周期 : public class Orders { //无参数构造 public Orders() { System.out.println("第一步 执行无参数构造创建 bean 实例"); } private String oname; public void setOname(String oname) { this.oname = oname; System.out.println("第二步 调用 set 方法设置属性值"); } //创建执行的初始化的方法 public void initMethod() { System.out.println("第三步 执行初始化的方法"); } //创建执行的销毁的方法 public void destroyMethod() { System.out.println("第五步 执行销毁的方法"); } } 复制代码 public class MyBeanPost implements BeanPostProcessor {//创建后置处理器实现类 @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("在初始化之前执行的方法"); return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("在初始化之后执行的方法"); return bean; } } 复制代码 复制代码 @Test public void testBean3() { // ApplicationContext context = // new ClassPathXmlApplicationContext("bean4.xml"); ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean4.xml"); Orders orders = context.getBean("orders", Orders.class); System.out.println("第四步 获取创建 bean 实例对象"); System.out.println(orders); //手动让 bean 实例销毁 context.close(); } 复制代码


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3