概述
目录
- 一、spring框架概述和简单入门:
- (1)、spring简单介绍:
- (2)、spring的第一个小案例:
- 二、IOC容器:
- (1)、IOC概念:
- (2)、IOC底层原理:
- (3)、IOC操作:Bean管理
- 1.基于xml方式创建对象:
- 2.基于xml方式注入属性:
- DI(依赖注入):
- 依赖注入的方式:
- 总结DI(依赖注入):
- spring的Bean的分类:
- Bean的作用域:
- IOC中Bean的生命周期:
- Spring中bean的装配方式总结:
- spring的Beans 的自动装配:
- 外部属性文件properties
- 使用注解加载配置文件:
一、spring框架概述和简单入门:
思维导图总结:
(1)、spring简单介绍:
Spring框架是由于软件开发的复杂性而创建的。Spring使用的是基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅仅限于服务器端的开发。从简单性、可测试性和松耦合性角度而言,绝大部分Java应用都可以从Spring中受益。
目的:解决企业应用开发的复杂性
功能:使用基本的JavaBean代替EJB,并提供了更多的企业应用功能
范围:任何Java应用
Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。
优点:
1.非侵入式设计
Spring是一种非侵入式(non-invasive)框架,它可以使应用程序代码对框架的依赖最小化。
2.方便解耦、简化开发
Spring就是一个大工厂,可以将所有对象的创建和依赖关系的维护工作都交给Spring容器的管理,大大的降低了组件之间的耦合性。
3.支持AOP
Spring提供了对AOP的支持,它允许将一些通用任务,如安全、事物、日志等进行集中式处理,从而提高了程序的复用性。
4.支持声明式事务处理
只需要通过配置就可以完成对事物的管理,而无须手动编程。
5.方便程序的测试
Spring提供了对Junit4的支持,可以通过注解方便的测试Spring程序。
6.方便集成各种优秀框架
Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如Struts、Hibernate、MyBatis、Quartz等)的直接支持。
7.降低Jave EE API的使用难度。
Spring对Java EE开发中非常难用的一些API(如JDBC、JavaMail等),都提供了封装,使这些API应用难度大大降低。
(2)、spring的第一个小案例:
第一步:下载spring5的依赖jar包。
下载地址:https://repo.spring.io/release/org/springframework/spring/
下载后的jar包在libs下找。有四个基本包。
第二步:打开idea,创建普通java工程。
第三步:导入spring5的基本包:
在项目下(与src并列)创建lib文件夹。放jar包
模块中导入jar
设置文件编译(compile)输出位置:
第四步:利用spring5创建对象:
4.1 创建一个java类User(在src下创建一个多级目录,然后在其中创建类User)
package com.fan.springtest;
public class User {
public void add() {
System.out.println("add---");
}
}
此类我们一般用于创建对象。不用spring框架的时候我们用new的方式。
此时用spring框架我们不用new方式创建对象了。
4.2 先创建spring的xml文件(src下创建):
<?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">
<!--配置User对象创建,class="com.fan.springtest.User"指定User的绝对路径-->
<bean id="user" class="com.fan.springtest.User">
</bean>
</beans>
第五步:
编写测试代码(单独创建一个测试文件夹《可以任意位置》):
package testspring;
import com.fan.springtest.User;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestSpring5 {
@Test
public void test01() {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
User user = context.getBean("user", User.class);
System.out.println(user);
System.out.println("===");
user.add();
}
}
测试结果:
com.fan.springtest.User@2e385cce
add—
小结:这里我们并没有手动创建User的实例(对象),是Spring通过ApplicationContext帮我们创建的放在IoC容器里。ApplicationContext是一个IoC容器接口,它所创建的对象都称作是bean,也就是xml文件里的这行配置信息。getBean方法就是从IoC容器里取得这个对象(根据标识id 和类名class),然后我们就可以调用该类的方法。
二、IOC容器:
(1)、IOC概念:
spring ioc指的是控制反转,IOC容器负责实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。交由Spring容器统一进行管理,从而实现松耦合。
IOC理论提出的观点大体是这样的:借助于“第三方”实现具有依赖关系的对象之间的解耦。如下图:
大家看到了吧,由于引进了中间位置的“第三方”,也就是IOC容器,使得A、B、C、D这4个对象没有了耦合关系,齿轮之间的传动全部依靠“第三方”了,全部对象的控制权全部上缴给“第三方”IOC容器,所以,IOC容器成了整个系统的关键核心,它起到了一种类似“粘合剂”的作用,把系统中的所有对象粘合在一起发挥作用,如果没有这个“粘合剂”,对象与对象之间会彼此失去联系,这就是有人把IOC容器比喻成“粘合剂”的由来。
我们再来做个试验:把上图中间的IOC容器拿掉,然后再来看看这套系统:
我们现在看到的画面,就是我们要实现整个系统所需要完成的全部内容。这时候,A、B、C、D这4个对象之间已经没有了耦合关系,彼此毫无联系,这样的话,当你在实现A的时候,根本无须再去考虑B、C和D了,对象之间的依赖关系已经降低到了最低程度。所以,如果真能实现IOC容器,对于系统开发而言,这将是一件多么美好的事情,参与开发的每一成员只要实现自己的类就可以了,跟别人没有任何关系!
我们再来看看,控制反转(IOC)到底为什么要起这么个名字?我们来对比一下:
软件系统在没有引入IOC容器之前,如图1所示,对象A依赖于对象B,那么对象A在初始化或者运行到某一点的时候,自己必须主动去创建对象B或者使用已经创建的对象B。无论是创建还是使用对象B,控制权都在自己手上。
软件系统在引入IOC容器之后,这种情形就完全改变了,如图3所示,由于IOC容器的加入,对象A与对象B之间失去了直接联系,所以,当对象A运行到需要对象B的时候,IOC容器会主动创建一个对象B注入到对象A需要的地方。
通过前后的对比,我们不难看出来:对象A获得依赖对象B的过程,由主动行为变为了被动行为,控制权颠倒过来了,这就是“控制反转”这个名称的由来。
(2)、IOC底层原理:
IOC过程:
1.在xml中配置创建的对象。
2.创建工厂类,在其中进行xml解析,解析出bean的完整类路径.
3.在工厂类中,使用类的完整路径进行反射创建类的对象。
IOC(接口):
其中FileSystemXmlApplicationContext的实现类的参数是写盘符目录,根据盘符目录去加载文件。
ClassPathXmlApplicationContext参数的类路径,是根据src下的类路径去加载配置文件。
(3)、IOC操作:Bean管理
1.Bean管理指的是两个操作:(1)Spring的创建对象和(2)Spring的注入属性值。
2.Bean管理操作有两种方式
1.基于xml配置文件方式实现
2.基于注解方式实现
Bean操作方式一:基于xml的方式
1.基于xml方式创建对象:
(1)在spring配置文件中,使用bean标签,标签里面添加对应的属性,就可以实现对象创建。
(2)在bean标签有很多属性,介绍常用属性
id属性:唯一标识。
class属性:l类全路径名(包类路径)
(3)创建对象的时候。默认也是执行的无参构造完成对象的创建。
2.基于xml方式注入属性:
(1)DI:依赖注入,就是注入属性(在创建对象的基础上才能注入属性)
DI(依赖注入):
在系统运行中,动态的向某个对象提供它所需要的其他对象。这一点是通过DI(Dependency Injection,依赖注入)来实现的
比如对象A需要操作数据库,以前我们总是要在A中自己编写代码来获得一个Connection对象,有了 spring我们就只需要告诉spring,A中需要一个Connection,至于这个Connection怎么构造,何时构造,A不需要知道。在系统运行时,spring会在适当的时候制造一个Connection,然后像打针一样,注射到A当中,这样就完成了对各个对象之间关系的控制。A需要依赖 Connection才能正常运行,而这个Connection是由spring注入到A中的,依赖注入的名字就这么来的。那么DI是如何实现的呢? Java 1.3之后一个重要特征是反射(reflection),它允许程序在运行的时候动态的生成对象、执行对象的方法、改变对象的属性,spring就是通过反射来实现注入的。
依赖注入的方式:
第一种注入方式:使用set方式进行注入:
第一步:创建类(创建对象的模板-类),定义属性和对应的set方法
代码:
package com.fan.springtest;
public class User {
private String name;
private int age;
//setter和getter方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"name='" + name + ''' +
", age=" + age +
'}';
}
public void add() {
System.out.println("add---");
}
}
第二步:在sping配置文件中配置对象的创建然后配置属性注入。
代码:
<?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">
<!--1.配置User的创建-->
<bean id="user" class="com.fan.springtest.User">
<!--2.使用property完成属性注入
name:类里面属性名称
value:向属性注入的值
-->
<property name="name" value="张三"></property>
<property name="age" value="18"></property>
</bean>
</beans>
测试:
package testspring;
import com.fan.springtest.User;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestSpring5 {
@Test
public void test01() {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
User user = context.getBean("user", User.class);
System.out.println(user.toString());//测试属性是否注入成功
System.out.println("===");
user.add();
}
}
结果能显示注入成功。
第二种注入方式:使用有参构造进行注入
(1)创建类,定义属性,创建属性对应的有参构造
代码:
package com.fan.springtest;
public class Order {
//使用有参构造来注入
private String oname;
private String addr;
//有参构造器
public Order(String oname, String addr) {
this.oname = oname;
this.addr = addr;
}
//toString测试方法
@Override
public String toString() {
return "Order{" +
"oname='" + oname + ''' +
", addr='" + addr + ''' +
'}';
}
}
(2)在spring配置文件中进行配置
代码如下:
<!--使用有参构造来注入-->
<bean id="order" class="com.fan.springtest.Order">
<constructor-arg name="oname" value="电脑"></constructor-arg>
<constructor-arg name="addr" value="西安"></constructor-arg>
</bean>
最后进行测试:
//测试有参构造器注入
Order order = context.getBean("order", Order.class);
System.out.println(order.toString());//测试属性是否注入成功
System.out.println("===");
3.p名称空间注入(本质set注入)(了解)
使用p名称空间注入,可以简化基于xml配置方式,底层用的还是 set注入。
第一步:添加p名称在配置文件中
第二步:进行属性注入,在bean标签里面进行操作。
4.注入其他类型的属性:
总结:普通属性注入使用property内的name–value搭配给属性赋值。
4.1注入外部bean类型属性:
总结:在属性property内,name-ref成对出现。
(1)创建两个类service和dao类(这里使用Person和Food类演示)
(2)在service中声明类类型dao,并调用dao里面的方法(这里代码简单用其他类演示);
(3)在spring配置文件中进行配置(生产对象和给对象属性赋值。)
<?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">
<!--1.配置对象的创建-->
<bean id="person" class="com.fan.domain.Person">
<!--2.使用property完成属性注入
name:类里面属性名称
ref:创建对象bean标签的id值
-->
<property name="name" value="张三"></property>
<property name="food" ref="food"></property>
</bean>
<bean id="food" class="com.fan.domain.Food"></bean>
4.2注入内部bean类型属性:
总结:在属性property内,name–bean成对出现。
Person类:
package com.fan.domain;
public class Person {
private String name;
private Food food;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Food getFood() {
return food;
}
public void setFood(Food food) {
this.food = food;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + ''' +
", food=" + food +
'}';
}
}
Food类:
package com.fan.domain;
public class Food {
private String name="蔬菜";//食物名称
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Food{" +
"name='" + name + ''' +
'}';
}
}
配置文件代码:
<?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">
<!--1.配置对象的创建-->
<bean id="person" class="com.fan.domain.Person">
<!--2.使用property完成属性注入
name:类里面属性名称
ref:创建对象bean标签的id值
-->
<property name="name" value="张三"></property>
<property name="food">
<!--内嵌一个完整的bean-->
<bean id="food" class="com.fan.domain.Food">
<property name="name" value="蔬菜"></property>
</bean>
</property>
</bean>
</beans>
测试:
package testspring;
import com.fan.domain.Person;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestBean {
@Test
public void test01(){
//加载配置文件
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml");
//通过配置文件获取对象
Person person = context.getBean("person", Person.class);
System.out.println(person);
}
}
4.3注入属性:级联赋值
第一种级联赋值:(需要类中有set方法)
第二种级联赋值:(需要类中有set,get方法)
4.4注入数组,集合类型属性(xml注入数组、集合属性):
集合类型这里例举四类: 数组, List, Map, Set, 其中每一种在xml文件中都有对应的配置方法, 举例说明如下:
创建Person类,定义数组,list,map,set类型属性,生成对应的set方法:
public class Person {
//1.数组类型属性
private String[] array;
//2.list集合类型属性
private List<String> list;
//3.map集合类型属性
private Map<String, String> map;
//4.set集合类型属性
private Set<String> set;
public void setArray(String[] array) {
this.array = array;
}
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 test(){
System.out.println(Arrays.toString(array));
System.out.println(list);
System.out.println(map);
System.out.println(set);
}
}
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">
<bean id="person" class="com.ryan.spring5.inputCollection.Person">
<!--这里泛型等值都是String类型,直接写值就可以-->
<!--数组类型属性注入-->
<property name="array">
<array>
<value>arr1</value>
<value>arr2</value>
</array>
</property>
<!--list类型属性注入-->
<property name="list">
<list>
<value>list1</value>
<value>list2</value>
</list>
</property>
<!--map类型属性注入-->
<property name="map">
<map>
<entry key="map-key1" value="map-value1"></entry>
<entry key="map-key2" value="map-value2"></entry>
</map>
</property>
<!--set类型属性注入-->
<property name="set">
<set>
<value>set1</value>
<value>set2</value>
</set>
</property>
</bean>
</beans>
测试:
public class Test {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml");
Person person= context.getBean("person", Person.class);
person.test();
}
}
在集合里面设置对象类型值
创建Family类:
public class Family {
private String calling;//成员称呼
public void setCalling(String calling) {
this.calling = calling;
}
@Override
public String toString() {
return "Family{" +
"calling='" + calling + ''' +
'}';
}
}
在Person类中添加内容为对象的集合类型:
...
//5.内容为对象的list集合类型属性
private List<Family> families;
public void setFamilies(List<Family> families) {
this.families = families;
}
...
在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">
<bean id="person" class="com.fan.spring5.inputCollection.Person">
<!--数组类型属性注入-->
<property name="array">
<array>
<value>arr1</value>
<value>arr2</value>
</array>
</property>
<!--list类型属性注入-->
<property name="list">
<list>
<value>list1</value>
<value>list2</value>
</list>
</property>
<!--map类型属性注入-->
<property name="map">
<map>
<entry key="map-key1" value="map-value1"></entry>
<entry key="map-key2" value="map-value2"></entry>
</map>
</property>
<!--set类型属性注入-->
<property name="set">
<set>
<value>set1</value>
<value>set2</value>
</set>
</property>
<!--内容为对象的list类型属性注入-->
<property name="families">
<list>
<!--集合中引用多个对象-->
<ref bean="father"></ref>
<ref bean="mother"></ref>
</list>
</property>
</bean>
<!--创建的多个对象-->
<bean id="father" class="com.fan.spring5.inputCollection.Family">
<property name="calling" value="father"></property>
</bean>
<bean id="mother" class="com.fan.spring5.inputCollection.Family">
<property name="calling" value="mother"></property>
</bean>
</beans>
把集合注入部分提取出来
创建Friends类(作为集合添加的对象使用):
public class Friends {
private List<String> name;
public void setName(List<String> name) {
this.name = name;
}
@Override
public String toString() {
return "Friends{" +
"name=" + name +
'}';
}
}
Person类中添加:
//6.提取出来的list集合属性
private List<Friends> friends;
public void setFriends(List<Friends> friends) {
this.friends = friends;
}
修改配置文件, 配置名称空间, 配置公共对象, 注入对象:
第一步:在spring配置文件中引入名称空间util
第二步:使用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="friendsList">
<value>张辽</value>
<value>太史慈</value>
<value>Lily</value>
</util:list>
<!--2.提取list集合类型属性注入使用-->
<bean id="friends" class="com.ryan.spring5.inputCollection.Friends">
<property name="name" ref="friendsList"></property>
</bean>
<bean id="ryan" class="com.ryan.spring5.inputCollection.Person">
<!--数组类型属性注入-->
<property name="array">
...
...
<property name="friends" ref="friends"></property>
</bean>
...
*配置名称空间: 在配置行中添加以下两行即可(复制相应行将关键字改成util即可):
xmlns:util=“http://www.springframework.org/schema/util”
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"
测试代码:
总结DI(依赖注入):
spring的Bean的分类:
1、普通bean
<bean id="" class="A">
spring直接创建A实例,并返回
2、FactoryBean
实现接口的类MyBean:
配置文件:
测试类:
一个特殊的bean,具有工厂生成对象的能力,只能生成特定的对象。bean必须使用 FactoryBean接口,此接口提供方法 getObject() 用于获得特定bean
<bean id="" class="FB">
//先创建FB实例,使用调用getObject()方法,并返回方法的返回值
FB fb = new FB();
return fb.getObject();
Bean的作用域:
spring 支持几种 bean 的作用域?
当通过spring容器创建一个Bean实例时,不仅可以完成Bean实例的实例化,还可以为Bean指定特定的作用域。Spring支持如下5种作用域:
singleton:单例模式,在整个Spring IoC容器中,使用singleton定义的Bean将只有一个实例
prototype:原型模式,每次通过容器的getBean方法获取prototype定义的Bean时,都将产生一个新的Bean实例
equest:对于每次HTTP请求,使用request定义的Bean都将产生一个新实例,即每次HTTP请求将会产生不同的Bean实例。只有在Web应用中使用Spring时,该作用域才有效
session:对于每次HTTP Session,使用session定义的Bean都将产生一个新实例。同样只有在Web应用中使用Spring时,该作用域才有效
globalsession:每个全局的HTTP Session,使用session定义的Bean都将产生一个新实例。典型情况下,仅在使用portlet context的时候有效。同样只有在Web应用中使用Spring时,该作用域才有效
其中比较常用的是singleton和prototype两种作用域。对于singleton作用域的Bean,每次请求该Bean都将获得相同的实例。容器负责跟踪Bean实例的状态,负责维护Bean实例的生命周期行为;如果一个Bean被设置成prototype作用域,程序每次请求该id的Bean,Spring都会新建一个Bean实例,然后返回给程序。在这种情况下,Spring容器仅仅使用new 关键字创建Bean实例,一旦创建成功,容器不在跟踪实例,也不会维护Bean实例的状态。
如果不指定Bean的作用域,Spring默认使用singleton作用域。Java在创建Java实例时,需要进行内存申请;销毁实例时,需要完成垃圾回收,这些工作都会导致系统开销的增加。因此,prototype作用域Bean的创建、销毁代价比较大。而singleton作用域的Bean实例一旦创建成功,可以重复使用。因此,除非必要,否则尽量避免将Bean被设置成prototype作用域。
常用的分为:单实例和多实例
1.在spring里面,默认情况下,bean是单实例对象。
2.如何设置单实例还是多实例:
(1)在spring配置文件bean标签里面有属性(scope)用于设置单实例还是多实例的
(2)scope属性的值
第一个值 默认值 ,singleton,表示的是单实例对象
第二个值 prototype,表示的是多实例对象
xml中的配置:
(3)singleton和prototype的区别:
第一个:singleton设置单实例,prototype用于设置多实例。
第二个:创建对象的时机不一样,singleton是加载spring配置文件(new ClassPathXmlApplicationContext(“bean2.xml”);)的时候就会创建单实例对象。而prototype是在调用getBean方法的时候创建多实例对象。
其他作用域:
IOC中Bean的生命周期:
5步的:
第一步,创建bean实例
第二步,通过set方法为bean的属性赋值
第三部,调用bean的初始化方法
第四步:对象的使用
第五步,调用bean的销毁方法
代码演示bean的生命周期:
定义一个类Order:
package com.fan.domain;
public class Order {
private String oname;
//无参构造
public Order() {
System.out.println("第一步,创建bean实例");
}
//setter方法
public void setOname(String oname) {
this.oname = oname;
System.out.println("第二步,通过set方法为bean的属性赋值");
}
//自定义的初始化方法
public void initMethod(){
System.out.println("第三部,调用bean的初始化方法");
}
//自定义的销毁方法
public void destroyMethod(){
System.out.println("第五步,调用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">
<!--1.配置User的创建-->
<bean id="order" class="com.fan.domain.Order" init-method="initMethod" destroy-method="destroyMethod">
<!--2.使用property完成属性注入
name:类里面属性名称
value:向属性注入的值
-->
<property name="oname" value="苹果手机"></property>
</bean>
</beans>
测试类的编写:
package testspring;
import com.fan.domain.Order;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import javax.xml.transform.Source;
public class TestBeanLiveTime {
@Test
public void test01(){
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean3.xml");
Order order = context.getBean("order", Order.class);
System.out.println("第四步:对象的使用");
System.out.println(order);
context.close();//手动关闭容器时。
}
}
测试结果:
第一步,创建bean实例
第二步,通过set方法为bean的属性赋值
第三部,调用bean的初始化方法
第四步:对象的使用
com.fan.domain.Order@1500b2f3
第五步,调用bean的销毁方法
7步的:
编写后置处理器MyEeanPost:
配置后置处理器
注意,后置处理器在初始化方法的前后执行。
Spring中bean的装配方式总结:
bean的装配方式可即为依赖注入的方式。
spring的Beans 的自动装配:
依赖注入有两种形式:构造器注入和setter注入。也就是我们在xml中写的一堆,如果bean太多我们还这样写基本是要成为码农了,更何况我们还有把有关联的bean装配起来,一旦bean很多,就不好维护了。
为此Spring使用自动装配解决这个问题,开发人员不用关心具体装配哪个bean的引用,识别工作由Spring来完成,因此一般配有自动监测来和自动装配配合完成。自动装配其实就是将依赖注入“自动化”的一个简化配置的操作,我们不再需要配置文件中使用ref来显示手动的装配注入一个对象。
Spring2.5之后提供了注解方式的自动装配。但是要使用这些注解,需要在配置文件中配置<context:annotation-config />。只有加上这一配置,或者maven中引入javax.annotation-api(@Resource属于这个javax包下的)和spring自带的org.springframework.beans才可以使用注解进行自动装配,默认情况下基于注解的装配是被禁用的。常用的自动装配注解有以下几种:@Autowired,,@Inject,@Qualifier,@Named。
Spring会在上下文中自动寻找,并自动给bean装配属性!
(自动装配一般适用于外部bean的注入):
自动装配模式
下列自动装配模式,它们可用于指示 Spring 容器为来使用自动装配进行依赖注入。你可以使用 元素的 autowire 属性为一个 bean 定义指定自动装配模式。
五种自动装配模式
1、no
这是默认的设置,它意味着没有自动装配,你应该使用显式的bean引用来连线。你不用为了连线做特殊的事。我们要手动的通过name-ref来注入外部bean(这种方式如果属性特别多,很麻烦,代码量特别大,不建议).如下代码:
<!--1.配置对象的创建-->
<bean id="person" class="com.fan.domain.Person">
<!--2.使用property完成属性注入
name:类里面属性名称
ref:创建对象bean标签的id值
-->
<property name="name" value="张三"></property>
<property name="food" ref="food"></property>
</bean>
<bean id="food" class="com.fan.domain.Food"></bean>
2、byName
当一个bean节点带有 autowire byName的属性时,将查找其类中所有的set方法名,获得将set去掉并且首字母小写的字符串,然后去spring容器中寻找是否有此字符串名称id的对象。如果有,就取出注入;如果没有,就报空指针异常。
3、byType
该模式表示根据Property的数据类型(Type)自动装配,Spring会总动寻找与属性类型相同的bean,若一个bean的数据类型,兼容另一个bean中Property的数据类型,则自动装配。
注意:使用byType首先需要保证同一类型的对象,在spring容器中唯一,若不唯一会报不唯一的异常。
4、constructor
使用构造方法完成对象注入,其实也是根据构造方法的参数类型进行对象查找,相当于采用byType的方式。即Spring会寻找与参数数据类型相同的bean,通过构造函数将其注入。
5、default
表示默认采用上一级标签的自动装配的取值。如果存在多个配置文件的话,那么每一个配置文件的自动装配方式都是独立的。
XML 配置里的 Bean 自动装配的缺点
1、在 Bean 配置文件里设置 autowire 属性进行自动装配将会装配 Bean 的所有属性,然而,,若只希望装配个别属性时, autowire 属性就不够灵活了。
2、autowire 属性要么根据类型自动装配, 要么根据名称自动装配, 不能两者兼而有之。
3、一般情况下,在实际的项目中很少使用自动装配功能,因为和自动装配功能所带来的好处比起来,明确清晰的配置文档更有说服力一些。
外部属性文件properties
引入外部属性文件配置数据库连接池:
第一步:准备一个德鲁伊的jar包,并放到lib文件夹下。
第二步:将jar包依赖引入到模块中。
第三步:创建外部属性文件,properties格式文件,写数据库信息。
注意!!
db.properties存放在src根目录下。
prop.driverClass=com.mysql.jdbc.Driver
prop.url=jdbc:mysql://localhost:3306/test
prop.username=root
prop.password=root
注意:properties文件的等号左边的key可以自定义名字,但是为了避免名字冲突带一个前缀prop.也可以是其他单词前缀。
第四步:把外部properties属性文件引入到spring配置文件中(需要引入context名称空间)。让spring帮我们读取配置文件的信息。
·
第五步:在spring配置文件中使用标签引入外部属性文件
<?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/beans/spring-context.xsd">
<!--引入外部属性文件-->
<context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
<!--配置连接池,利用spring表达式${}获取外部文件的值-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${prop.driverClass}"></property>
<property name="url" value="${prop.url}"></property>
<property name="username" value="${prop.username}"></property>
<property name="password" value="${prop.password}"></property>
</bean>
</beans>
使用注解加载配置文件:
使用@ProtertySource
@PropertySouce是spring3.1开始引入的基于java config的注解。
通过@PropertySource注解将properties配置文件中的值存储到Spring的 Environment中,Environment接口提供方法去读取配置文件中的值,参数是properties文件中定义的key值。
2.1 用法1- @PropertySource和@Value
创建java配置类
@Configuration
@PropertySource("classpath:jdbc.properties")
public class PropertiesWithJavaConfig {
@Value(${jdbc.driver})
private String driver;
@Value(${jdbc.url})
private String url;
@Value(${jdbc.username})
private String username;
@Value(${jdbc.password})
private String password;
//要想使用@Value 用${}占位符注入属性,这个bean是必须的,这个就是占位bean,另一种方式是不用value直接用Envirment变量直接getProperty('key')
@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
}
2.2 用法2-通过Environment设置
@Configuration
@PropertySource("classpath:jdbc.properties")
public class PropertiesWithJavaConfig {
@Autowired
private Environment env;
}
接着就可以用env.getProperty(“jdbc.driver”)得到相应的属性值
https://www.cnblogs.com/whx7762/p/7885735.html
最后
以上就是勤恳大树为你收集整理的spring5详解-xml方式一、spring框架概述和简单入门:二、IOC容器:的全部内容,希望文章能够帮你解决spring5详解-xml方式一、spring框架概述和简单入门:二、IOC容器:所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复