赞
踩
思维导图总结:
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应用难度大大降低。
第一步:下载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),然后我们就可以调用该类的方法。
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的过程,由主动行为变为了被动行为,控制权颠倒过来了,这就是“控制反转”这个名称的由来。
IOC过程:
1.在xml中配置创建的对象。
2.创建工厂类,在其中进行xml解析,解析出bean的完整类路径.
3.在工厂类中,使用类的完整路径进行反射创建类的对象。
IOC(接口):
其中FileSystemXmlApplicationContext的实现类的参数是写盘符目录,根据盘符目录去加载文件。
ClassPathXmlApplicationContext参数的类路径,是根据src下的类路径去加载配置文件。
1.Bean管理指的是两个操作:(1)Spring的创建对象和(2)Spring的注入属性值。
2.Bean管理操作有两种方式
1.基于xml配置文件方式实现
2.基于注解方式实现
Bean操作方式一:基于xml的方式
(1)在spring配置文件中,使用bean标签,标签里面添加对应的属性,就可以实现对象创建。
(2)在bean标签有很多属性,介绍常用属性
id属性:唯一标识。
class属性:l类全路径名(包类路径)
(3)创建对象的时候。默认也是执行的无参构造完成对象的创建。
(1)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"
测试代码:
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();
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方法的时候创建多实例对象。
其他作用域:
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:
配置后置处理器
注意,后置处理器在初始化方法的前后执行。
bean的装配方式可即为依赖注入的方式。
依赖注入有两种形式:构造器注入和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、一般情况下,在实际的项目中很少使用自动装配功能,因为和自动装配功能所带来的好处比起来,明确清晰的配置文档更有说服力一些。
引入外部属性文件配置数据库连接池:
第一步:准备一个德鲁伊的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
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。