Spring(一):概述和IOC容器
文章目录
1. Spring概述
Spring是一个开源框架,它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为 J2EE应用程序开发提供集成的框架。Spring 使用基本的 JavaBean 来完成以前只可能由 EJB完成的事情。然而,Spring 的用途不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何 Java 应用都可以从 Spring 中受益。
Spring 的核心是控制反转(IoC) 和面向切面 (AOP) 。简单来说,Spring 是一个分层的 JavaSE/EEfull- - stack( 一站式) 轻量级开源框架。
1.1 Spring的优点
- 方便解耦,简化开发。
Spring 就是一个大工厂,可以将所有对象的创建和依赖关系的维护,交给 Spring 管理。 - AOP 编程的支持
Spring 提供面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等功能。 - 声明式事务的支持
只需要通过配置就可以完成对事务的管理,而无须手动编程。 - 方便程序的测试
Spring 对 Junit4 支持,可以通过注解方便的测试 Spring 程序。 - 方便集成各种优秀的框架
Spring 不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如:Struts2、Hibernate、MyBatis、Quartz 等)的直接支持。 - 降低 JavaEE API 的使用难度
Spring 对 JavaEE 开发中非常难用的一些 API(JDBC、JavaMail、远程调用等),都提供了封装,使这些 API 应用难度大大降低。
2. IOC容器
IOC—Inversion of Control,即“控制反转”,不是什么技术,而是一种设计思想。在 Java 开发中,Ioc 意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。创建对象。
DI(Dependency Injection,依赖注入),IOC 的一个重点是在系统运行中,动态的向某个对象提供它所需要的其他对象。这一点是通过 DI(Dependency Injection依赖注入)来实现的。给对象属性赋值。
2.1 Spring入门案例
- maven配置pom.xml导入依赖
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>RELEASE</version>
</dependency>
</dependencies>
- 创建实体类User
public class User {
public User() {
System.out.println("创建User对象");
}
}
- 创建配置文件并进行java类的配置
注意: Bean标签只能配置Java类,不能配置接口和抽象类
<?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="user"
class="com.zmysna.entity.User" >
</bean>
<beans>
- 测试
public class ACTest {
@Test
public void demo01start() {
//从类路径下加载bean.xml文件,创建IOC容器
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
//使用id名从容器中取得一个对象
User user = (User) ac.getBean("user");
System.out.println(user);
}
}
2.2 配置文件<bean>标签细节
2.2.1 <bean>标签属性及其说明
属性 | 说明 |
---|---|
id | 对象的引用名称:一定要唯一;一次只能定义一个引用名称。 |
name | 对象的引用名称:可以定义多个引用名称。 |
class | 类的全限定名称 |
scope | 设置bean的作用范围,取值如下: singleton:单例,默认值 prototype:多例 request:web项目中,将对象存入request域中 session: web项目中,将对象存入session域中 globalsession:web项目中,应用在集群环境中 如果没有集群环境,相当域session |
init-method | 指定类中初始化方法的名称,构造方法之后执行 |
destroy-method | 指定类中销毁方法名称,在销毁spring容器前执行 |
lazy-init | 设置为true表示延迟创建对象。第一次使用才创建对象。 只对单例对象有效 |
2.2.2 使用
- 修改User类,添加init方法和destory方法
public class User {
public User() {
System.out.println("创建User对象");
}
public void init() {
System.out.println("User初始化");
}
public void destory() {
System.out.println("User对象销毁");
}
}
- 修改配置文件
<?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="user"
name="user2,user5"
class="com.zmysna.entity.User"
lazy-init="true"
init-method="init"
destroy-method="destory"
scope="singleton">
</bean>
<beans>
- 测试
@Test
public void demo02Detail() {
//从类路径下加载bean.xml文件,创建IOC容器
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
//断点在下一语句,运行观察控制台是否打印信息,向下调试继续观察。
//使用id名从容器中取得一个对象
User user = (User) ac.getBean("user");
/*
name属性:通过逗号或者空格分隔引用名称
通过name属性的引用名称从容器中获得对象
*/
User user2 = (User) ac.getBean("user2");
User user5 = (User) ac.getBean("user5");
User user3 = (User) ac.getBean("user3");
//测试singleton
System.out.println(user2 == user3);
//关闭容器,继续观察控制台是否执行销毁方法。
ac.close();
}
2.3 创建容器的方式
public class ACTest {
@Test
public void test_ac1(){
// 创建容器
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
}
@Test
public void test_ac2(){
// 创建容器
ApplicationContext ac = new FileSystemXmlApplicationContext("D:\\classes\\IdeaProjects\\spring01_02_ioc\\src\\main\\resources\\bean.xml");
}
@Test
public void test_ac3(){
// 创建容器
ApplicationContext ac = new AnnotationConfigApplicationContext(App.class);
}
/**
* 通过BeanFactory方式创建容器,默认延迟加载
*/
@Test
public void demo02CreateFactory() {
Resource resource = new ClassPathResource("bean.xml");
BeanFactory factory = new XmlBeanFactory(resource);
}
}
2.4 创建对象的方式
方式1:默认无参数构造函数创建对象
方式2:工厂类的静态方法创建对象
方式3:工厂类的实例方法创建对象
方式1
class User{}
bean.xml
<bean id="user" class="com..User"/>
测试:
ac.getBean("user");
方式2
配置文件
<!--使用工厂的静态方法创建对象-->
<bean id="user1" class="com.zmysna.factory.BeanFactory" factory-method="createUser" lazy-init="true">
</bean>
测试
/**
* 测试工厂静态方法创建对象
*/
@Test
public void demo03FStaticMethod() {
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
User user1 = (User) ac.getBean("user1");
}
方式3
配置文件
<!--配置工厂的普通方法创建对象-->
<bean id="userfactory" class="com.zmysna.factory.BeanFactory"></bean>
<bean id="user2" factory-bean="userfactory" factory-method="getUser" ></bean>
测试
/**
* 测试工厂的普通方法创建对象
*/
@Test
public void demo04FactoryMethod(){
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
User user2 = (User) ac.getBean("user2");
}
2.5 依赖注入的方式
- Person实体类
package com.zmysna.entity;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Properties;
public class Person {
private int age;
private String name;
private List list;
private int[] arr;
private Map map;
private Properties properties;
private String string;
public void setList(List list) {
this.list = list;
}
public void setArr(int[] arr) {
this.arr = arr;
}
public void setMap(Map map) {
this.map = map;
}
@Override
public String toString() {
return "Person{" +
"age=" + age +
", name='" + name + '\'' +
", list=" + list +
", arr=" + Arrays.toString(arr) +
", map=" + map +
", properties=" + properties +
'}';
}
public void setProperties(Properties properties) {
this.properties = properties;
}
public void setAge(int age) {
this.age = age;
}
public void setName(String name) {
this.name = name;
}
public Person(int age, String name){
this.age = age;
this.name = name;
}
public void set(String string) {
this.string =string;
}
public String get() {
return string;
}
}
-
配置person的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" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!--创建一个字符串,给person引用--> <bean id="str" class="java.lang.String"> <constructor-arg index="0" value="yiyi"></constructor-arg> </bean> <bean id="person" class="com.zmysna.entity.Person"> <!--通过构造器注入 --> <constructor-arg index="0" value="100"/> <constructor-arg index="1" value="zhangsan"/> <!-- 通过property注入 注意:name表示的属性值必须在 Person类中有相应的set方法 --> <property name="age" value="10"></property> <property name="name" ref="str"></property> <!--注入集合和数组类型的依赖--> <property name="list"> <list> <value>isList</value> </list> </property> <property name="arr"> <array> <value>11</value> </array> </property> <property name="map"> <map> <entry key="11" value="love"></entry> </map> </property> <property name="properties"> <props> <prop key="isprops">yes</prop> </props> </property> </bean> <!--通过p名称空间注入--> <bean id="person3" class="com.zmysna.entity.Person" p:list="lds" p:age="12"> <constructor-arg index="0" value="11"/> <constructor-arg index="1" value="zhangsan"/> </bean> </beans>