全面学习Spring框架入门与提高(含代码)

这一篇文章我将和大家一起回顾整个Spring框架技术,由于内容较多,内容共分为三大部分。每一篇都从简到难地安排了一些小知识点,东西是当时我老师讲的,现在将知识点都整理下来,供大家一起讨论学习,也方便以后自己复习。如果有不对的地方欢迎大家指正。

1.初识Spring框架,声明周期和延时加载…
2.注入,自动装配,注入集合类型,注入properties类型…
3.Spring简介,对象获取方式,对象声明周期…

<1>.初识Spring框架,声明周期和延时加载…

1. 框架

框架是一套已经编写好的程序结构,开发者在使用框架之后,可以在此基础之上进行开发,而不必关心偏底层的问题。

框架通常可以提高开发效率,一定程度上还解决了一些其它的问题,可能是性能的问题,或者数据安全的问题,或者程度的可维护性的问题等等。

框架具体的表现就是一系列的jar包,并且,可能改变原有的编程方式或流程。

普通的jar包,例如dom4jmysql-connector等,只是实现了某个功能,相当于是一套工具。

2. 课程任务

  • Spring框架

  • SpringMVC框架

  • MyBatis框架

3. Spring框架

3.1. 作用

创建和管理对象

传统的创建对象的方法是:Object obj = new Object();

使用Spring框架后:Object obj = 框架.getXXX();

即:开发者无需关注对象的创建过程,改由框架来创建,当需要对象时,通过框架获取即可。

传统的管理对象可能有:student.setName("张三同学");

使用Spring框架后,无需执行相关代码,通过配置,获取对象时,相关属性就已经有值了。

3.2. 项目准备

先创建Maven项目,勾选Create a simple projectGroup Idcn.tedu.springArtifact IdSPRING-01Packaging选择war,创建好项目后,默认项目是出错的,需要生成web.xml文件。

使用Spring之前,需要添加相关依赖,artifactIdspring-webmvc,且groupIdorg.springframework,版本通常选择3.2或以上版本,但,目前尚不推荐使用5.x版本。

<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-webmvc</artifactId>
	<version>4.3.9.RELEASE</version>
</dependency>

以上代码,应该添加到项目的pom.xml<dependencies>节点的内部。

然后,下载得到applicationContext.xml文件,复制到项目中的src\main\resources文件夹下:

在这里插入图片描述
这里我将applicationContext.xml文件中的所有代码粘贴在这,如下(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:context="http://www.springframework.org/schema/context" 
	xmlns:jdbc="http://www.springframework.org/schema/jdbc"  
	xmlns:jee="http://www.springframework.org/schema/jee" 
	xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:aop="http://www.springframework.org/schema/aop" 
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xmlns:util="http://www.springframework.org/schema/util"
	xmlns:jpa="http://www.springframework.org/schema/data/jpa"
	xsi:schemaLocation="
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
		http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
		http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
		http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
		http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
		http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd">
	
	<bean id="date" class="java.util.Date" />
	<bean id="user" class="cn.tedu.spring.User" />       <!-- 要求类中要有无参构造方法,对构造方法的权限没有要求 -->
	
	<!-- 2. 类中存在静态工厂方法 -->
	<bean id="calendar" class="java.util.Calendar" factory-method="getInstance"></bean>
	<bean id="huaweiphone" class="cn.tedu.spring.HuaWeiphone" factory-method="create"/>  
	
	<!--  -->
	<bean id="carFactory" class="cn.tedu.spring.CarFactory" />
	<bean id="car" class="cn.tedu.spring.Car" factory-bean="carFactory" factory-method="makeCar"></bean>
	
	
	<bean id="student" class="cn.tedu.spring.Student" scope="singleton" lazy-init="true" init-method="init" destroy-method="destroy"/>   <!--懒汉式的初始化,在加载Spring的配置文件之前,就创建完对象 -->
	
	
</beans>

3.3. 通过Spring获取对象–类中存在无参数构造方法(常用)

在Spring的配置文件(applicationContext.xml)中,添加:

<bean id="date" class="java.util.Date">
</bean>

以上配置中,class表示“类”,取值应该是类的全名,即包名和类名,id是自定义的名称,通常使用类名并且首字母改为小写,例如类名是Date,则id值为date,如果类名是Student,则id值为student

完成配置后,就可以在程序中,通过Spring根据date名称获取java.util.Date的对象,可以在src\main\java中创建可执行的Java类:

package cn.tedu.spring;

public class SpringTest {

	public static void main(String[] args) {
		
	}
	
}

然后,编写程序:

public static void main(String[] args) {
	// 加载Spring的配置文件,获取Spring容器
	ApplicationContext ac
		= new ClassPathXmlApplicationContext(
				"applicationContext.xml");
	
	// 通过Spring容器获取对象
	Date date = (Date) ac.getBean("date");
	
	// 测试输出
	System.out.println(date);
}

在这里插入图片描述

自定义User类,在Spring的配置文件中添加配置,最终,在程序中,获取User类的对象。

以上操作,要求类中存在无参数的构造方法,如果不具备条件,则:

Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'user' defined in class path resource [applicationContext.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [cn.tedu.spring.User]: No default constructor found; nested exception is java.lang.NoSuchMethodException: cn.tedu.spring.User.<init>()

Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [cn.tedu.spring.User]: No default constructor found; nested exception is java.lang.NoSuchMethodException: cn.tedu.spring.User.<init>()

Caused by: java.lang.NoSuchMethodException: cn.tedu.spring.User.<init>()

这种做法对构造方法的访问权限并没有任何要求,即使是private权限,也不影响Spring创建对象!

此次实现的代码中,关于ac变量,会提示警告:ac is never closed,即:推荐调用ac.close()以释放资源,但是,ApplicationContext接口中并没有声明close()方法,所以,应该将ac的类型声明为AbstractApplicationContext

3.4. 通过Spring获取对象–类中存在静态工厂方法(不常用)

**工厂方法:**调用后可以返回类的对象的方法,也可以理解为生产对象的方法。

Calendar为例,它是一个抽象类,是不可以直接通过new 构造方法()此类语法创建对象的!但是,在这个类中,有static Calendar getInstance()方法,这个方法,就称之为Calendar类的静态工厂方法

在Spring的配置文件中,配置:

<bean id="calendar"
	class="java.util.Calendar"
	factory-method="getInstance"></bean>

以上配置中,factory-method属性的值是静态工厂方法的名称。

配置时,无论是类的全名,还是方法的名称,都必须是已知条件。

练习:自定义类HuaWeiPhone,通过静态工厂方法,获取该类的对象!

关于类:

package cn.tedu.spring;

public class HuaWeiPhone {
	
	// 使得当前类不存在无参数的构造方法
	public HuaWeiPhone(Object obj){
		super();
	}
	
	// 静态工厂方法
	public static HuaWeiPhone create() {
		return new HuaWeiPhone(null);
	}

}

关于配置:

<bean id="huaWeiPhone"
	class="cn.tedu.spring.HuaWeiPhone"
	factory-method="create"></bean>

3.5. 通过Spring获取对象–存在实例工厂方法(不常用)

实例工厂方法:通过某个实例(对象)调用的方法,并且,这个方法可以返回某个类的对象,是生产对象的方法。

假设存在某类需要被获取对象,不满足前序的2种条件:

public class Car {
	public Car(Object obj) {
	}
}

则需要另一个类中存在工厂方法,可以创建它的对象

public class CarFactory {
	public Car makeCar() {
		return new Car(null);
	}
}

在配置时:

<bean id="carFactory" 
	class="cn.tedu.spring.CarFactory"></bean>
<bean id="car" class="cn.tedu.spring.Car"
	factory-bean="carFactory"
	factory-method="makeCar">
</bean>

以上配置中,factory-bean的值是工厂类的<bean>节点的id属性值。

在这里插入图片描述

3.6. 通过Spring获取对象–小结

通过Spring创建对象,然后从Spring容器中获取对象,需要:

  1. 类中存在无参数的构造方法;

  2. 类中存在静态的工厂方法;

  3. 存在实例工厂方法。

以上3种方式中,第2种和第3种的使用频率较低,原因是满足条件的类较少。

3.7. 由Spring管理的对象的作用域

单例:单一的实例,即在同一时刻,某个类的对象是唯一的!

由Spring所管理的对象,默认都是单例的,在配置时,通过scope属性可以配置是否单例,默认取值为singleton,当取值为prototype时,是非单例的!

<bean id="student"
	class="cn.tedu.spring.Student"
	scope="prototype"></bean>

单例模式可以区分为:懒汉式、饿汉式。

默认情况下,由Spring管理的单例对象是饿汉式的,通过lazy-init属性可以调整,该属性的值是布尔类型。

<bean id="student"
	class="cn.tedu.spring.Student"
	scope="singleton"
	lazy-init="true"></bean>

3.8. 由Spring管理的对象的生命周期

仅由Spring管理的、单例的对象存在生命周期问题!

开发者可以在任何自定义的、由Spring管理的类中添加初始化方法和销毁方法,方法必须是void和无参数的,例如:

public class Stduent {

	// 初始化方法
	public void init() {
		System.out.println("Student.init()");
	}
	
	// 销毁方法
	public void destroy() {
		System.out.println("Student.destroy()");
	}

}

然后,在Spring的配置文件中进行配置:

<bean id="student"
	class="cn.tedu.spring.Student"
	init-method="init"
	destroy-method="destroy"></bean>

注意:对于非单例的对象而言,生命周期方法是没有意义的。

3.9. 通过SET方式注入属性的值

基本概念:通过Spring的配置,确定某个类中的某个属性的值,使得最终获取对象时,属性是已经被赋值的。

假设存在UserDao类,在类中有String usernameString password表示访问数据库的用户名和密码:

public class UserDao {

	// 模拟:访问数据库的用户名
	String username;
	
	// 模拟:访问数据库的密码
	String password;
	
}

需要注入值的属性,必须有set方法,即设置它的值的方法,且方法名称必须以set作为前缀:

public void setUsername(String u) {
	username = u;
}

然后,在Spring的配置文件中:

<bean id="userDao" 
	class="cn.tedu.spring.UserDao">
	<property name="username" 
		value="root">
	</property>
</bean>

即:添加子级<property>节点,在该节点,配置namevalue,其中,name表示属性,value表示值。

注意:在配置的name时,值应该是需要注入的属性的set方法名称中不包含set的部分,且首字母是小写的!

在这里插入图片描述


其它

1. 关于Maven中依赖出错

在添加依赖后,下载到的jar包文件可能是已损坏的,或数据不完整的,可能表现为:下载的jar包的数量不正确,或者,编写代码时,某个类无法识别等……

解决方案:

  1. 打开Eclipse的设置,找到Maven > User Settings,面板中的Local Repository就是本地仓库文件夹;

  2. 关闭Eclipse,因为已经打开的项目可能引用了本地仓库文件夹中的某个jar包,如果Eclipse正在运行,可能导致后续的删除操作无法执行;

  3. 打开本地仓库文件夹,删除出错的jar包文件(通常jar包文件对于新生来说不易于查找,所以,简单的操作方式就是将整个本地仓库文件夹全部删除);

  4. 打开Eclipse,找到需要开发的项目,点击右键,选择Maven > Update Project,在弹出的对话框中,选中Force update ...选项,然后,开始更新即可。

2. Resource leak

Resource leak表示“内存溢出”(内存泄露)。

模拟情景:假设存在D:/a.txt,在程序中,通过FileInputStream fis访问该文件,在访问过程中,如果出现异常,导致程序结束,然后,JVM中垃圾回收机制尝试回收垃圾时,找到了fis,但是,前序fis并没有正常关闭,仍然连接着硬盘上的a.txt文件,在JVM看来,这个fis仍处于使用状态,不是垃圾!但是,以程序员的角度来看,fis是一个变量,当程序崩溃时,这个变量就已经无法继续使用,就是个垃圾!所以,就会出现“已经无法继续使用的对象,却不会被视为垃圾数据,无法被回收!”

如果以上类似的垃圾数据越来越多,就会导致可用内存越来越少,当达到极端状态时,就会出现“内存溢出”!

所以,其实,少量的内存溢出,并没有明显的危害!但是,作为开发者,应该尽量的避免任何可能出现的内存溢出!

解决内存溢出的核心:尽早释放不再使用的资源,例如流、数据库访问的相关对象、XML的读写工具等连接型资源,对于可能抛出异常的代码,应该添加finally代码块,并在其中释放资源。

3. 单例模式示例

public class King {
	private static King king;

	private King() {
	}

	public static King getKing() {
		if (king == null) {
			king = new King();
		}
		return king;
	}
}

以上是懒汉式单例模式的代码,且,没有解释线程安全问题。

<2>.注入,自动装配,注入集合类型,注入properties类型…

前课

  1. Spring的作用:创建和管理对象

  2. 配置无参数构造方法的类

  3. Spring管理对象的作用域与生命周期

  4. 通过SET方法为属性注入值

1. 【常用】通过SET方法注入属性的值(续)

如果需要注入的属性的值并不是基本值(基本数据类型或String),则值需要配置为一个<bean>,且,注入值时,使用ref="bean-id"来确定属性的值:

在这里插入图片描述

小结:为属性注入值时,如果类型是基本型,使用value进行配置,如果类型是引用,需要配置另一个bean来创建值的对象,然后通过ref进行配置。

2. 【不常用】通过构造方法注入属性的值

首先,类中应该存在带参数的构造方法:

public class User {

	public String name;
	public String from;
	
	public User(String name, String from) {
		super();
		this.name = name;
		this.from = from;
	}

}

在配置时,通过<constructor-arg>配置构造方法的参数的值,如果有个参数,则需要多个节点,每个节点配置1个属性,且每个节点都必须添加index属性,表示配置的是第几个参数,取值为从0开始编号的数字,根据值的类型不同,继续配置valueref来决定属性的值:

<bean id="user"
	class="cn.tedu.spring.User">
	<constructor-arg index="0"
		value="LiuGB">
	</constructor-arg>
	<constructor-arg index="1"
		value="HeBei">
	</constructor-arg>
</bean>

3. 注入集合类型的值

例如存在类:

public class SampleBean {
	public List<String> names;

	public void setName(List<String> names) {
		this.names = names;
	}
}

然后,添加配置:

<bean id="sampleBean"
	class="cn.tedu.spring.SampleBean">
	<property name="names">
		<list>
			<value>Jame</value>
			<value>Lucy</value>
			<value>David</value>
			<value>Tom</value>
			<value>Alex</value>
		</list>
	</property>	
</bean>

因为names属性的类型是List,所以,在注入值时,<property>节点中添加子级的<list>节点进行配置,在<list>中的每组<value>节点表示1个值。

如果属性是Set类型的,则使用<set>节点进行配置即可:

<property name="cities">
	<set>
		<value>Hangzhou</value>
		<value>Beijing</value>
		<value>Shanghai</value>
		<value>Shenzhen</value>
		<value>Guangzhou</value>
	</set>
</property>	

如果属性是Map类型的,则需要使用<map>及其子级的<entry>节点进行配置:

<property name="session">
	<map>
		<entry key="username" value="Jack"/>
		<entry key="password" value="1234"/>
		<entry key="from" value="Nanjing"/>
	</map>
</property>

还有Properties类型,通常在使用时,会自定义一个???.properties文件,例如:

url=jdbc:mysql://192.168.0.251:3306/db_name?useUnicode=true&characterEncoding=utf8
driver=com.mysql.jdbc.Driver
username=root
password=root
initialSize=2
maxActive=10

然后,通过Spring框架读取该文件的信息:

<util:properties id="config"
	location="classpath:db.properties">
</util:properties>

以上<util:properties>节点本质上也是一个<bean>,在注入值时:

<property name="dbConfig"
	ref="config">
</property>

当然,Properties类型的节点是可以直接配置的,例如:

<property name="dbConfig">
	<props>
		<prop key="name">Jack</prop>
	</props>
</property>

事实上,关于ListSetMap也存在<util:list>等类似节点,使用频率较低。

以上2种为Properties类型的数据注入值的做法都是有用的!而为ListSetMap类型的数据注入值的应用场景相对较少。

4. 自动装配(Auto-wire)

自动装配表示由Spring自动的为属性注入值,即:无需配置各<property>节点!可以解决需要注入多个值时添加多个<property>节点导致的配置项太多的问题!

当需要自动装配时,为<bean>节点添加autowire属性的配置即可,常用的取值有byNamebyType

当取值为byName

表示“根据名称实现自动装配”,即:当某个<bean>配置了autowire="byName"时,Spring会检索当前类中的SET系列方法,根据SET方法的名称还原出属性名,并且尝试在Spring容器中找到bean-id相同的对象,如果找到,则自动为这些属性赋值,如果没有找到,也不会报告任何错误,只是相关属性没有被赋值而已!这种做法本质上还是通过SET方式注入的,所以,需要被注入的属性一定要有SET方法!而SET方法的名称一定与值对应的bean-id是匹配的!

在这里插入图片描述

当取值为byType

顾名思义,当取值为byType时,会“根据类型实现自动装配”,例如private IUserDao userDao;时,会尝试在Spring容器中查询类型符合IUserDao类型的<bean>,如果找到,则自动装配,否则,将跳过。

使用这种做法时,无需关心各个名称(属性名、方法名、bean-id),但是,需要保证“能匹配的bean只有1个”,否则,会出现NoUniqueBeanDefinitionException,并提示例如:expected single matching bean but found 2: userDao2,userDao

小结

自动装配还有其它模式,暂不需要了解。

记住byNamebyType的意义,及byType的注意事项。

自动装配虽然简单,但是,存在“是否注入值不明确”的问题,即:只能看到哪些<bean>配置了autowire="byName"autowire="byType",但是,这些类中的属性是否成功的注入了值、哪些属性是需要注入值的……等问题并不明确,也无从可查,所以,关于这种自动装配的做法是不推荐的!

5. Spring表达式

Spring表达式的基本格式是#{名称},用于表示某个值,甚至,值可以是来自另一个<bean>的某个属性!

当某个注入的属性值是通过Spring表达式得到的,则应该配置为value=#{}格式。

关于Spring表达式:

  • 如果获取另一个<bean>中的某属性值,则使用#{bean-id.属性名}

  • 如果获取另一个<bean>中的某List集合中的某个值,则使用#{bean-id.List集合名[索引]}

  • 如果获取另一个<bean>中的某Map集合中的某个值,则使用#{bean-id.Map集合名.key},还可以是#{bean-id.Map集合名['key']}


1. 什么时候需要自定义构造方法?

如果某个类没有显式的添加构造方法,则编译器会自动添加公有的、无参数的构造方法,例如:

public class User {
}

等效于:

public class User {

	public User() {
		super();
	}

}

如果显式的添加了构造方法,则编译器就不会添加任何构造方法!

通常,需要自定义构造方法的原因:不允许使用公有的、无参数的构造方法。

具体的表现:

  1. 限制创建对象,例如:单例模式;

  2. 强制要求得到某数据;

  3. 快速创建对象、确定某些属性的值。

2. List和Set的特性

List:顺序的,先存入的数据在前,后存入的数据在后;元素可重复;

Set:散列的,先存入的数据不一定在前,后存入的数据不一定在后;元素不可重复,如果尝试添加相同的数据,在Set中并不会不多项该元素,关于“是否相同”的评定依据是“2个数据的equals()对比结果为true,并且hashCode()的返回值必须相同”!

Set的本质是一个只关心key不关心value的Map!

Model:DAO
View:html/jsp
Controller:Servlet

View > Controller > Model(Service + DAO)

Service:登录
Service:注册
	DAO:根据用户名查询用户信息

<3>.Spring简介,对象获取方式,对象生命周期…

1. 前2天小结

  1. 【理解】通过Spring获取对象的3种条件:无参构造方法、静态工厂方法、实例方法;

  2. 【理解】由Spring管理的对象的作用域及生命周期:单例、懒加载、生命周期方法;

  3. 【重要】通过SET方式注入属性的值,理解value和ref的使用;

  4. 【了解】通过构造方法注入属性的值;

  5. 【了解】注入集合类型的属性的值,包括:List / Set / Map;

  6. 【重要】注入Properties类型的属性的值,读取*.properties文件;

  7. 【理解】自动装配的作用,取值为byName与byType的特性;

  8. 【重要】Spring表达式

2. Spring注解(Annotation)

2.1. 基本概念

例如@Override就是注解,在Spring中定义了一些注解,可以取代在Spring的XML文件中的配置!

2.2. 通过Spring获取对象

案例目标:创建cn.tedu.spring.dao.UserDao类,然后,创建cn.tedu.spring.test.SpringTest类,通过Spring获取UserDao的对象。

在Spring中,有几种通用注解:

  • @Component

  • @Controller

  • @Service

  • @Repository

这些注解是添加在类的声明之前的,表示这个类是一个“组件”,是希望由Spring进行管理的!

以上4个注解中,@Component表示“通用组件类”,@Controller表示“控制器类”,@Service表示“业务类”,@Repository表示“数据访问类/持久层处理的类”,这4个注解只有语义的区别,从功能和用法上来说,是完全一样的!即,如果愿意的话,可以用@Service注解添加在控制器类的声明之前,但是,不推荐这样做。

仅仅只是添加注解是不够的,还需要在Spring的配置文件中开启组件扫描:

<context:component-scan 
	base-package="cn.tedu.spring.dao" />

以上配置中,base-package表示根包,即当配置为cn.tedu.spring时,其子级包例如cn.tedu.spring.daocn.tedu.spring.service等都在扫描范围之内!

如果没有显式的指定bean-id,默认为使用类名且首字母改为小写,例如UserDao类的bean-id就是userDao

以上注解都可以添加配置,例如@Service("bean-id")

小结:通用注解共4个,其功能、用法都是完全相同的,只是表达的语义不同,添加的注解的类,并且在组件扫描范围之内,就会被Spring所管理,在配置组件扫描时,配置的包是“根包”,其范围不宜过大,在添加注解时,还可以自定义bean-id。

2.3. 作用域与生命周期

由Spring管理的对象,默认是饿汉式的单例的,通过在类的声明之前添加注解@Lazy可以调整:

@Component("userDao")
@Lazy(true)
public class UserDao {
}

还可以通过@Scope("singleton")@Scope("prototype")注解调整是否为单例的:

@Service
@Scope("prototype")
public class UserService {
}

关于生命周期方法,依然是先自定义生命周期方法,在初始化方法之前添加@PostConstruct注解,在销毁方法之前添加@PreDestroy注解,这2个注解都是Java EE的注解,来自javax包下,所以,在使用之前,需要为当前项目添加Tomcat运行环境,代码部分例如:

@Component("userDao")
public class UserDao {
	
	public UserDao() {
		System.out.println("UserDao的构造方法被执行!");
	}
	
	@PostConstruct
	public void init() {
		System.out.println("UserDao.init()");
	}
	
	@PreDestroy
	public void destroy() {
		System.out.println("UserDao.destroy()");
	}

}

注意:如果导入他人的项目,或者本机更换了Tomcat软件,都需要重新勾选项目属性中的Targeted Runtimes中的Tomcat。

2.4. 【重要】自动装配

假设在UserDao中存在public void findUserByUsername()方法,然后,在UserService中声明了private UserDao userDao;属性,并且,存在public void login()方法,在方法内部,调用了userDaofindUserByUsername()方法:

@Component("userDao")
public class UserDao {

	public void findUserByUsername() {
		System.out.println("UserDao.findUserByUsername()");
	}
	
}

@Service
public class UserService {
	
	private UserDao userDao;
	
	public void login() {
		System.out.println("UserService.login()");
		userDao.findUserByUsername();
	}

}

在需要自动装配属性值的属性之前,添加@Autowired注解,就可以实现自动装配:

@Autowired
private UserDao userDao;

注意:使用注解的自动装配不需要为属性添加SET方法!

添加@Autowired实现自动装配,其装配方式是byType的,所以,在使用时,需要确保“其对应的值在Spring容器中应该是有且仅有1个的”!

通过@Resource注解也可以实现自动装配!它是优先根据byName实现自动装配,在没有显式的指定bean-id的情况下,如果无法byName装配,则会尝试根据byType实现自动装配。

在实际使用时,可以自由选取以上2个注解中的任何一个!因为,在实际应用中,命名应该是规范的,并且,匹配类型的也应该是有且仅有1个。

以上2个注解中,@Autowired是Spring的环境中的注解类,而@Resource是Java EE环境中的注解类。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值