spring ioc踏出第一步
spring IOC(容器) AOP(面向切面编程)
IOC容器:他的功能就是可以整合像 Structs2 、Hibernate、Mybatis;
IOC:控制反转;所谓的控制就是控制资源的获取方法,获取资源的方式又分为主动和被动方式;
什么是主动式:
就是要使用什么资源我们就new 出来
BookServlet bs = new BookServlet();
什么是被动式?
例如要使用一个userService, UserService userService; 把他当成变量来声明。
容器:就是管理所有组件(有功能的类);假设,一个servlet受容器管理,service也受容器管理;容器可以自动的探查出那些组件需要另外一些组件;容器帮我们创建service对象,并且将service对象赋值。其实容器就是一个中介,例如现在最大的电商淘宝就是一个巨型容器,以前的卖家有货,买家有需要才能卖,什么时候卖,买什么,中间夹杂着许多因素。使卖家与买家之间的耦合度太高,中间的联系太过紧密,这时淘宝的出现就是一个第三方容器,他将货物与需求都管理着,买家什么时候都可以在淘宝上询问价格和商品信息,卖家也可以不像之前那样看买家什么时候买。直接由淘宝这个平台进行管理,分配,展示,交付。这样耦合度就减少了,也就做到了解耦的操作。IOC其实也是一种解耦思想。
ApplicationContext是IOC容器接口,ClassPathXmlApplicationContext 代表当前引用的xml 配置文件在这个classpath路径中。
当所创建的spring配置文件放在当前类路径下;使用new CassPathXMLApplicationContext(“applicationContext.xml”);
当所创建的配置文件没在类路径下,例如放在了D盘,所以要使用
new FileSystemXmlApplicationContext(“D://ioc.xml”);这个类的构造函数。
spring容器帮我们创建了对象,但具体是什么时候帮我们创建了呢?
其实呀,当这句代码执行完之后,配置文件中的对象已经创建完成,容器启动,构造方法就已经执行了。
默认情况下创建的组件(对象)都是单实例的,
IOC容器创建组件(对象)的时候(property)会利用setter方法为JavaBean的属性进行赋值,而Javabean的属性名是由getter/setter方法名决定的,并不是类中定义的私有属性,例如setLastName(String name); 在配置文件中设置所以建议使用系统自动生成的set/get方法。
如果配置的时候对于同一个类配置了多个对象,然后在获取对应那个的时候通过类型获取就会抛出如下异常:org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'main.java.domain.Student' available: expected single matching bean but found 2: stu3,students
意思就是按照Student.class这个类去找,应该只允许找到一个对象就是但离得,但是出现了两个,stu3和students导致出错,解决方法:
Student stu3 = (Student) context.getBean(“students”,Student.class);//获取student对象
getBean(“bean_id”,bean.class);传入bean的id属性和类型,亦可以通过id获取对象。
当构造方法重载时,我们怎样在spring的配置文件中进行配置?
如果指定了name属性给构造方法那就可以精确匹配我们想要的构造方法并给对象设置值,创建出对象。
但如果没有指定name属性,容器默认是按照构造方法中的参数列表顺序一一对应,当顺序与参数列表的顺序不一致时,我们可以添加index属性值来使参数能够与正确的类型对相应。
<constructor-arg index="0" value="happy"/>
<constructor-arg index="1" value="19"/>
当构造方法重载后参数类型也发生了变化,例如:
第一个构造方法的第二个参数是integer,第二个构造方法第二个参数是String,如果还像往常一样直接指定value值,运行就会
是的,sex对应的是age的值,我们想要的是使用第一个构造方法创建对象
因此要给这个构造方法加入type属性,指定明确的类型
`<bean id="person_05" class="main.java.domain.Person">
<constructor-arg value="小明"></constructor-arg>
<constructor-arg value="18" index="1" type="java.lang.Integer"></constructor-arg>
</bean>`
这样就匹配正确的构造方法了。
感觉不指定name属性是真的麻烦。。
P命名空间(就是在xml配置文件中给重复的标签起了个别名,用来放置标签重复)
第一步:导入名称空间
<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 "
xmlns:p="http://www.springframework.org/schema/p"
//这一行就是导入了p名称空间
>
第二步:使用名称空间给对象赋值
<bean id="person_06" class="main.java.domain.Person" p:age="22" p:name="搜索" scope="singleton">
</bean>
person construct…
搜索要开始工作了。。22
正确的为各种数据类型赋值。
测试使用null赋值,默认就是null。
<bean id="person01" class="com.main.java.bean.Person">
<property name="name">
<null/>
</property>
</bean>
对于复杂类型,例如对象,集合等,属性写在标签内部。
<bean id="person_05" class="main.java.domain.Person">
<constructor-arg value="小明"></constructor-arg>
<constructor-arg value="18" index="1" type="java.lang.Integer"></constructor-arg>
<property ref="stu3" name="s1" ></property>
</bean>
ref是引用类型,这里引用了一个对象,Student类型。
运行下面这段代码结果是true
Object stu3 = context.getBean("stu3");
Person person_05 = (Person) context.getBean("person_05");
Student s1 = person_05.getS1();
System.out.println(s1==stu3);//true
从IOC容器中取得的对象与利用person对象调用自身student属性获取的对象是同一个,想要给一个对象中设置另个对象当属性还有一种方法
<bean id="person_05" class="main.java.domain.Person">
<constructor-arg value="小明"></constructor-arg>
<constructor-arg value="18" index="1" type="java.lang.Integer"></constructor-arg>
<!--<property ref="stu3" name="s1" ></property>-->
<property name="s1">
<bean class="main.java.domain.Student">
<property name="name" value="小光">
</property>
</bean>
</property>
</bean>
作用与使用对象的引用效果一样。不同的是,这个相当于是字节new出来的一个Student对象,上面的输出就是false,属性设置与引用的一样。是内部bean与之前的没有关系,ref引用的是外部的对想。
对于内部的bean即使给他加上id,我们在外部想要获取他,那也是不行的,内部的bean只能定义,不能获取到,通过getBean(“InnerId”);是会报错的。
属性是map类型
<property name="map">
<map>
<entry key="1" value="xxx"></entry>
<entry key="2" value="zzz"></entry>
<entry key="3" value="ccc"></entry>
<entry key="5" >
<bean class="java.bean.person">
<perproty name=""name value="张三"></perproty>
</bean>
</entry>
</map>
</property>
属性时list类型
<property name="list">
<list>
<value>小武</value>
<value>小两</value>
</ref="stu3" name="student">
<bean class="java.bean.car">
<perproty name="car" value="hongguang"></perproty>
</bean>
</list>
</property>
属性是properties
<property name="properties">
<props>//键值对都是字符类型,如果props标签体中没有<prop>就相当于只new properties();
<prop key="driverClass">com.mysql.jdbc.driver</prop>
<prop key="username">root</prop>
<prop key="password">root</prop>
</props>
</property>
使用util命名空间,
需要引入命名空间
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.1.xsd"
xmlns="http://www.springframework.org/schema/beans">
<bean>
<!-- 相当于new LinkHashMap(),这个util map在别的对象中可以被引用-->
<!-- 使用util的集合必须要加上id属性才可以被其他对象共享-->
<util:map id="myMap">
<entry key="k1" value="reset"></entry>
<entry key="k2" value="123"></entry>
<entry key="k1" >
<bean class="main.java.domain.Student"></bean>
</entry>
</util:map>
<util:list id="myList">
<value>123</value>
<list></list>
<ref bean="myMap"/>
</util:list>
<util:set id="mySet">
</util:set>
<util:properties id="myPro">
</util:properties>
</bean>
</beans>
使用util的集合必须要加上id属性才可以被其他对象共享。
级联属性:就是属性的属性,例如person类中有关于car的对象,car自身又有color这个属性,而color和person就是级联属性。
将person中的car对象的价格price改为360000,
测试代码:
private ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("config/bean.xml");
@Test
public void test2()
{
Person person01 = (Person) context.getBean("person01");
Car car = person01.getCar();
System.out.println("person的car:"+car.toString());
Object car01 = context.getBean("car01");
System.out.println("容器中的car: "+car01.toString());
}
配置文件:
<?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 "
xmlns:p="http://www.springframework.org/schema/p"
>
<bean id="person01" class="main.java.domain.Person">
<property name="name" value="憨憨"></property>
<property name="age" value="36"></property>
<!--级联属性-->
<property name="car" ref="car01"></property>
<property name="car.price" value="360000"></property>
</bean>
<bean id="car01" class="main.java.domain.Car">
<property name="name" value="宝马"></property>
<property name="color" value="black"></property>
<property name="price" value="1000000"></property>
</bean>
</beans>
运行结果:
person的car:Car{name=‘宝马’, price=360000, color=‘black’}
容器中的car: Car{name=‘宝马’, price=360000, color=‘black’}
通过继承对象属性来实现bean配置信息的重用。
如果有两个person对象A、B,他们两个除了姓名不一样,其余属性都一样,那么如果A的信息已确定,B的个人属性大部分信息都可以从A身上获得。直接只需要修改直接独特的那部分信息。
<bean class="main.java.domain.Person" id="personA">
<property name="name" value="小A"></property>
<property name="age" value="26"></property>
</bean>
<!--属性的重用,通过类似于继承关系 配置parent属性来制定继承那个对象的信息-->
<bean id="personB" parent="personA">
<property name="name" value="小B"></property>
</bean>
测试:
@Test
public void test3()
{
Object personB = context.getBean("personB");
Object personA = context.getBean("personA");
System.out.println("B: "+personB);
System.out.println("A: "+personA);
}
结果:
B: Person{name=‘小B’, age=26, sex=‘null’, s1=null}
A: Person{name=‘小A’, age=26, sex=‘null’, s1=null}
现在我想让A永远当成一个类似于父类的东西,只能被继承配置信息,这个只要在加上abstract属性并设置为true就行。这个代表不能被直接获取 。
默认情况下,对象的创建顺序就是在配置文件中bean写的前后顺序,它会一个bean一个bean的逐个创建,但现在要想改变默认的这个顺序,那具体要怎样更改?
例如:
<bean id="car02" class="main.java.domain.Car"></bean>
<bean id="person06" class="main.java.domain.Person"></bean>
<bean id="student05" class="main.java.domain.Student"></bean>
上面的对象创建顺序默认就是 car02,person06,student05,但现在要想让person06, student05在car02之前创建就要在car02的bean标签中加入
depends-on属性,
<bean id="car02" class="main.java.domain.Car" depends-on="person_06,student05"></bean>
<bean id="person06" class="main.java.domain.Person"></bean>
<bean id="student05" class="main.java.domain.Student"></bean>
这样顺序就变成了我们想要的,同样构造函数的顺序也发生了变化。
bean的作用域:指定bean是否是单实例或多实例
prototype: 多实例;
1.
容器启动时不会主动创建多实例的bean,
2.
获取才创建这个bean
3.
每次获取都会创建一个新的对象。
singleton: 单实例,且默认就是单实例
1.
在容器启动完成之前就已经创建好了对象,保存在了容器中。
2.
任何获取都是之前创建好的那个对象;
request:在web环境中同一次请求创建一个bean
session:在web环境中同义词会话创建一个bean。
spring ioc踏出第一步的更多相关文章
- Spring Boot-开启第一步
Spring Boot开发的目的是为了简化Spring应用的开发,使用Spring Boot可以零配置开启一个Spring应用.这得益于Spring Boot中的自动配置组件,如果开发者觉得默认的配置 ...
- 踏出第一步——安装并跑通python程序
一.首先学会安装python软件 1.在浏览器下输入安装python软件的官方网址. 点击打开链接 2.在界面上点击"Downloads"下的"Windows" ...
- 【初探Spring】------Spring IOC(二):初始化过程---简介
首先我们先来看看如下一段代码 ClassPathResource resource = new ClassPathResource("bean.xml"); DefaultList ...
- 我的自定义框架 || 基于Spring Boot || 第一步
今天在园子里面看到一位大神写的springboot做的框架,感觉挺不错,遂想起来自己还没有一个属于自己的框架,决定先将大神做好的拿过来,然后加入自己觉得需要的模块,不断完善 目前直接复制粘贴过来的,后 ...
- Spring的IOC容器第一辑
一.Spring的IOC容器概述 Spring的IOC的过程也被称为依赖注入(DI),那么对象可以通过构造函数参数,工厂方法的参数或在工厂方法构造或返回的对象实例上设置的属性来定义它们的依赖关系,然后 ...
- 【初探Spring】------Spring IOC(三):初始化过程---Resource定位
我们知道Spring的IoC起到了一个容器的作用,其中装得都是各种各样的Bean.同时在我们刚刚开始学习Spring的时候都是通过xml文件来定义Bean,Spring会某种方式加载这些xml文件,然 ...
- Spring IoC源码解析——Bean的创建和初始化
Spring介绍 Spring(http://spring.io/)是一个轻量级的Java 开发框架,同时也是轻量级的IoC和AOP的容器框架,主要是针对JavaBean的生命周期进行管理的轻量级容器 ...
- Spring:源码解读Spring IOC原理
Spring IOC设计原理解析:本文乃学习整理参考而来 一. 什么是Ioc/DI? 二. Spring IOC体系结构 (1) BeanFactory (2) BeanDefinition 三. I ...
- 轻松理解spring IOC
spring IOC(Inversion of control)即控制反转 概念:一,spring框架的核心之一 二,控制权由对象本身转向容器:由容器根据配置文件去创建实例并创建各个实例之间的依赖关系 ...
随机推荐
- Fabric v2.0中的隐私数据
文章来源于https://hyperledger-fabric.readthedocs.io/en/release-2.0/ 私有数据集在v1.4中提出,一直使用的是隐私数据集方式,即建立一个隐私数据 ...
- 关于Switch Case的优化
switch case虽然是代替if else而出现的,并不好维护,有时候使用switch还不如使用if else. 但没有别的东西能代替switch case了吗?答案当然是否定的,现在就有两种方式 ...
- Qingcloud_MySQL Plus(Xenon) 高可用搭建实验
实验:Xenon on 5.7.30 Xenon (MySQL Plus) 是青云Qingcloud的一个开源项目,号称金融级别强一致性的高可用解决方案,项目地址为 https://github.co ...
- 第七周jieba分词
import jieba txt = open("聊斋志异简写版.txt", "r", encoding='utf-8').read() words = jie ...
- Mybatis学习-日志与分页
日志 为什么需要日志 如果一个数据库操作出现了异常,需要排错,那么日志就是最好的助手 Mybatis通过使用内置的日志工厂提供日志功能,有一下几种实现方式: SLF4J Apache Commons ...
- Java——排序算法
java排序从大的分类来看,可以分为内排序和外排序:其中,在排序过程中只使用了内存的排序称为内排序:内存和外存结合使用的排序成为外排序. 下面讲的都是内排序. 内排序在细分可以这样分: 1.选择排序: ...
- python 的基本语法
python3 默认的编码格式 :utf-8 标识符: 1.可以是数字,字母,下划线组成 2.不能以数字开头 3.不能以保留字命名(保留字即是关键字,比如"print") 4.区分 ...
- 检验实时3D像素流送平台好坏的七个标准!(上)
将交互式3D像素流送技术作为有价值的企业工具之后,就该寻找像素流送服务供应商了.问题在于交互式3D像素流送是一种新兴技术,因此很难知道要问供应商的正确问题.在开始使用之前,这里有7个问题,您应该从候选 ...
- 前置机器学习(五):30分钟掌握常用Matplitlib用法
Matplotlib 是建立在NumPy基础之上的Python绘图库,是在机器学习中用于数据可视化的工具. 我们在前面的文章讲过NumPy的用法,这里我们就不展开讨论NumPy的相关知识了. Matp ...
- 感知机:Perceptron Learning Algorithm
感知机是支持向量机SVM和神经网络的基础 f = sign(wx+b) 这样看起来好像是LR是差不多的,LR是用的sigmoid函数,PLA是用的sign符号函数,两者都是线性分类器,主要的差别在于策 ...