Spring简单使用

Spring 是一种轻量级开发框架,旨在提高开发人员的开发效率以及系统的可维护性。

我们一般说 Spring 框架指的都是 Spring Framework,它是很多模块的集合,使用这些模块可以很方便地协助我们进行开发。

在这里插入图片描述

Spring Core: 基础,可以说 Spring 其他所有的功能都需要依赖于该类库。主要提供 IoC 依赖注入功能。
Spring Aspects : 该模块为与AspectJ的集成提供支持。
Spring AOP :提供了面向切面的编程实现。
Spring JDBC : Java数据库连接。
Spring JMS :Java消息服务。
Spring ORM : 用于支持Hibernate等ORM工具。
Spring Web : 为创建Web应用程序提供支持。
Spring Test : 提供了对 JUnit 和 TestNG 测试的支持。

IOC理解

IoC(Inverse of Control:控制反转)是一种设计思想,就是 将原本在程序中手动创建对象的控制权,交由Spring框架来管理。IoC 在其他语言中也有应用,并非 Spring 特有。 IoC 容器是 Spring 用来实现 IoC 的载体, IoC 容器实际上就是个Map(key,value),Map 中存放的是各种对象。

将对象之间的相互依赖关系交给 IoC 容器来管理,并由 IoC 容器完成对象的注入。这样可以很大程度上简化应用的开发,把应用从复杂的依赖关系中解放出来。 IoC 容器就像是一个工厂一样,当我们需要创建一个对象的时候,只需要配置好配置文件/注解即可,完全不用考虑对象是如何被创建出来的。 在实际项目中一个 Service 类可能有几百甚至上千个类作为它的底层,假如我们需要实例化这个 Service,你可能要每次都要搞清这个 Service 所有底层类的构造函数,这可能会把人逼疯。如果利用 IoC 的话,你只需要配置好,然后在需要的地方引用就行了,这大大增加了项目的可维护性且降低了开发难度。

总的来说就是“解耦”——解除了“开发人员”与“对象管理”之间的耦合,提高了开发效率。

Spring环境搭建

首先需要导入依赖的jar包,或者maven配置依赖,四个核心包和一个日志包:

在这里插入图片描述

然后需要在src下新建applicationContext.xml,applicationContext.xml 配置的信息最终存储到了AppliationContext 容器中。

在这里插入图片描述

<?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">
    <!-- id表示获取到对象标识
    	 class 创建哪个类的对象
     -->
    <bean id="peo" class="com.test.pojo.People"/>
</beans>

spring 配置文件是基于schema的,schema文件的类型是xsd,xsd文件用来描述一组xml文件需要遵守的规则。

通过<bean>标签创建需要Spring管理的对象。

<bean id="peo" class="com.test.pojo.People"/>

其中属性id表示获取到对象标识,属性class表示创建哪个类的对象。

这样就已经可以使用Spring来创建对象了:

package com.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.test.pojo.People;

public class Test {
	public static void main(String[] args) {
		ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
		People people = ac.getBean("peo",People.class);
		System.out.println(people);
	}
}

People类如下:

package com.test.pojo;

public class People {
	private int id;
	private String name;
	
	public People() {
		super();
		System.out.println("执行构造方法");
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	@Override
	public String toString() {
		return "People [id=" + id + ", name=" + name + "]";
	}
}

不管是程序员手动创建对象,还是Spring创建对象,都是需要通过构造方法来创建。由于我们只创建了对象,并没有给对象属性赋值,所以创建的对象都是默认值,即id默认值为0,String类型的name默认值为null。

在这里插入图片描述

在Spring中,<bean>标签对应的对象默认是单例的,当Spring加载applicationContext.xml文件的的时候便会自动创建<bean>标签对应的单例对象,之后的使用过程中取出,不管取出使用多少次都是单例对象。

例如,我们把getBean方法注释掉,只保留一行加载applicationContext.xml文件的代码:

package com.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.test.pojo.People;

public class Test {
	public static void main(String[] args) {
		ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
		//People people = ac.getBean("peo",People.class);
		//System.out.println(people);
	}
}

在这里插入图片描述

可以发现,依然执行了构造方法创建了对象,随后我们可以getBean两次,再比较一下它们的地址是否一样:

package com.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.test.pojo.People;

public class Test {
	public static void main(String[] args) {
		ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
		People people = ac.getBean("peo",People.class);
		System.out.println(people);

People people2 = ac.getBean("peo",People.class);
		System.out.println(people2);
		
		System.out.println(people == people);
	}
}

在这里插入图片描述

“==”判断为true说明两个对象是同一个。

Spring创建对象的三种方式

Spring创建对象有三种创建方式:前面那种方式便是直接通过构造方法创建,另外还有通过实例工厂和静态工厂创建的方式。

直接通过构造方法创建

前面的例子中,Spring创建对象走的是唯一的无参构造方法,在类中可能不止一个构造方法,可能还会有参数不同的有参构造方法,这样我们就需要在<bean>标签中指定参数,例如:

<bean id="peo" class="com.test.pojo.People">
	<!-- ref引用另一个bean   value 基本数据类型或String等 -->
	<constructor-arg index="0" name="id" type="int" value="123"></constructor-arg>
	<constructor-arg index="1" name="name" type="java.lang.String" value="张三"></constructor-arg>
</bean>

<constructor-arg>标签表示的是构造方法的参数,index属性用于表示参数的顺序,type用于表示参数的数据类型,value表示需要传入的参数值,name属性表示参数名。

People类如下;

package com.test.pojo;

public class People {
	private int id;
	private String name;

	public People() {
		super();
		System.out.println("执行构造方法");
	}
	public People(int id, String name) {
		super();
		this.id = id;
		this.name = name;
		System.out.println("执行有参构造");
	}
	public People(Integer id, String name) {
		super();
		this.id = id;
		this.name = name;
		System.out.println("执行有参构造Integer");
	}
	public People(String name,int id) {
		super();
		this.id = id;
		this.name = name;
		System.out.println("执行有参构造1111111");
	}
	
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	@Override
	public String toString() {
		return "People [id=" + id + ", name=" + name + "]";
	}
}

在这里插入图片描述

可见走的是第一个构造方法,即标签中配置的参数类型和顺序对应着构造方法的参数类型和顺序。

如果设定的条件匹配多个构造方法则会执行最后的构造方法。

例如,我们去掉<bean>标签中<constructor-arg>的index属性和type属性,那么满足的构造方法可以是People(int id, String name)和public People(String name,int id),至于执行哪个构造方法取决于它们在类中的位置,默认会执行最后一个符合的构造方法。

People(int id, String name)在最后:

在这里插入图片描述
在这里插入图片描述

public People(String name,int id)在最后:

在这里插入图片描述

在这里插入图片描述

通过实例工厂创建

通过实例工厂创建对象需要先构造实例工厂,再生产对象。

package com.test.pojo;

public class PeopleFactory {
	public static People newInstance(){
		return new People(1,"测试");
	}
}

然后在applicationContext.xml中配置工厂对象和需要创建的对象:


这就可以通过实例工厂获取People对象了:

package com.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.test.pojo.People;

public class Test {
	public static void main(String[] args) {
		ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
		People people = ac.getBean("peo1",People.class);
		System.out.println(people);
	}
}

通过静态工厂创建

通过静态工厂创建对象只需要将上面实例工厂的newInstance方法用static修饰即可,同时在applicationContext.xml中配置工厂,不需要再配置被创建的对象了。

package com.test.pojo;

public class PeopleFactory {
	public static People newInstance(){
		return new People(1,"测试");
	}
}
<bean id="peo2" class="com.test.pojo.PeopleFactory" factory-method="newInstance"></bean> 

给Bean的属性赋值(注入)

Spring中给Bean的属性赋值的操作一般叫做“注入”,一般有两种注入方式:通过构造方法注入和通过设值注入(set方法)。

通过构造方法注入就是前面通过带参数的构造方法创建对象的方式。

通过设值注入需要在<bean>标签中使用<property>标签。

基本数据类型或String

如果需要注入的属性是基本数据类型或String,则可以直接使用<property>标签中的name和value属性,或者使用子标签<value>

等效于:

<bean id="peo" class="com.bjsxt.pojo.People">
	<property name="id">
		<value>456</value>
	</property>
	<property name="name">
		<value>zhangsan</value>
	</property>
</bean>

Set集合

如果属性是Set集合,则需要在<property>中使用<set>标签,然后再在子标签<value>中设置每个元素的值。

<property name="sets">
    <set>
    	<value>1</value>
    	<value>2</value>
    	<value>3</value>
    	<value>4</value>
    </set>
</property>

List<?>集合

如果属性是List<?>则需要在<property>标签中使用子标签<list>,然后再在子标签<value>中设置每个元素的值。

<property name="list">
	<list>
		<value>1</value>
		<value>2</value>
		<value>3</value>
	</list>
</property>

如果list中只有一个值,可以直接在标签设值。

<property name="list" value="1"></property>

数组

如果是一维数组:

<property name="strs" >
	<array>
    	<value>1</value>
    	<value>2</value>
    	<value>3</value>
    </array>
</property>

如果是多维数组:

<property name="strs" >
    <array>
    	<array>
    		<value>1</value>
    		<value>2</value>
    		<value>3</value>	
    	</array>
    	<array>
    		<value>4</value>
    		<value>5</value>
    		<value>6</value>	
    	</array>
    </array>
</property>

Map

如果属性是map,则需要使用<map>标签,并使用<entry>标签设置键值对。

<property name="map">
    <map>
    	<entry key="a" value="b" ></entry>
    	<entry key="c" value="d" ></entry>
    </map>
</property>

我们创建一个包含上述所有类型属性的People类来测试一下:

package com.test.pojo;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class People {
	private int id;
	private String name;
	private Set<String> sets;
	private List<String> list;
	private String [] strs;
	private Map<String,String> map;
	
	@Override
	public String toString() {
		return "People [id=" + id + ", name=" + name + ", sets=" + sets + ", list=" + list + ", strs="
				+ Arrays.toString(strs) + ", map=" + map + "]";
	}
	public Map<String, String> getMap() {
		return map;
	}
	public void setMap(Map<String, String> map) {
		this.map = map;
	}
	public String[] getStrs() {
		return strs;
	}
	public void setStrs(String[] strs) {
		this.strs = strs;
	}
	public List<String> getList() {
		return list;
	}
	public void setList(List<String> list) {
		this.list = list;
	}
	public Set<String> getSets() {
		return sets;
	}
	public void setSets(Set<String> sets) {
		this.sets = sets;
	}
	public People() {
		super();
		System.out.println("执行构造方法");
	}
	public People(int id, String name) {
		super();
		this.id = id;
		this.name = name;
		System.out.println("执行有参构造");
	}
	public People(Integer id, String name) {
		super();
		this.id = id;
		this.name = name;
		System.out.println("执行有参构造Integer");
	}
	public People(String name,int id) {
		super();
		this.id = id;
		this.name = name;
		System.out.println("执行有参构造1111111");
	}
	
	public int getId() {
		return id;
	}
	public void setId(int id) {
		System.out.println("执行setId");
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		System.out.println("执行setName");
		this.name = name;
	}
}

配置文件applicationContext.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="peo" class="com.test.pojo.People">
    	<property name="id">
    		<value>456</value>
    	</property>
    	
    	<property name="name">
    		<value>zhangsan</value>
    	</property>
    	
    	<property name="sets">
    		<set>
    			<value>1</value>
    			<value>2</value>
    			<value>3</value>
    			<value>4</value>
    		</set>
    	</property>
    	
    	<property name="list" value="1"></property>
    	
    	<property name="strs" >
    		<array>
    			<value>1</value>
    			<value>2</value>
    			<value>3</value>
    		</array>
    	</property>
    	
    	<property name="map">
    		<map>
    			<entry key="a" value="b" >
    			</entry>
    			<entry key="c" value="d" >
    			</entry>
    		</map>
    	</property>
    </bean>
</beans>

测试代码:

package com.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.test.pojo.People;

public class Test {
	public static void main(String[] args) {
		ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
		People people = ac.getBean("peo",People.class);
		
		System.out.println(people);
	}
}

在这里插入图片描述

依赖注入(DI)

依赖注入(Dependency Injection)简称“DI”,如果一个类需要依赖另一个类的对象时,需要在<property>标签中使用ref属性引用另外一个<bean>标签的id属性。

 <bean id="peo" class="com.test.pojo.People">	
	<property name="desk" ref="desk"></property>
 </bean>
    
 <bean id="desk" class="com.test.pojo.Desk">
    <property name="id" value="1"></property>
    <property name="price" value="12"></property>
 </bean>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值