一.spring的概述
1.Spring框架是什么
Spring 是分层的 Java SE/EE 应用 full-stack 轻量级开源框架,以 IoC(Inverse Of Control:反转控制)和 AOP(Aspect Oriented Programming:面向切面编程)为内核,提供了展现层 SpringMVC 和持久层 Spring JDBC 以及业务层事务管理等众多的企业级应用技术,还能整合开源世界众多 著名的第三方框架和类库,逐渐成为使用最多的 Java EE 企业应用开源框架。
2. Spring起源
1997 年 IBM 提出了 EJB 的思想 1998 年, SUN 制定开发标准规范 EJB1.0 1999 年, EJB1.1 发布 2001 年, EJB2.0 发布 2003 年, EJB2.1 发布 2006 年, EJB3.0 发布 Rod Johnson(spring 之父) Expert One-to-One J2EE Design and Development(2002) 阐述了 J2EE 使用 EJB 开发设计的优点及解决方案 Expert One-to-One J2EE Development without EJB(2004) 阐述了 J2EE 开发不使用 EJB 的解决方式(Spring 雏形)
3. spring框架的优势
方便解耦,简化开发 通过 Spring 提供的 IoC 容器,可以将对象间的依赖关系交由 Spring 进行控制,避免硬编码所造成的过度程序耦合。用户也不必再为单例模式类、属性文件解析等这些很底层的需求编写代码,可以更专注于上层的应用。
AOP 编程的支持 通过 Spring 的 AOP 功能,方便进行面向切面的编程,许多不容易用传统 OOP 实现的功能可以通过 AOP 轻松应付。
声明式事务的支持 可以将我们从单调烦闷的事务管理代码中解脱出来,通过声明式方式灵活的进行事务的管理,提高开发效率和质量。
方便程序的测试 可以用非容器依赖的编程方式进行几乎所有的测试工作,测试不再是昂贵的操作,而是随手可做的事情。
方便集成各种优秀框架 Spring 可以降低各种框架的使用难度,提供了对各种优秀框架(Struts、Hibernate、Hessian、 Quartz等)的直接支持。
降低 JavaEE API 的使用难度
Spring 对 JavaEE API(如 JDBC、JDBCTemplate . JavaMail、远程调用等)进行了薄薄的封装层,使这些 API 的使用难度大为降低。
Java源码是经典学习范例
Spring 的源代码设计精妙、结构清晰、匠心独用,处处体现着大师对 Java 设计模式灵活运用以及对 Java 技术的高深造诣。它的源代码无意是 Java 技术*的最佳实践的范例.
4. Spring架构体系
Test :用于测试使用
Core container:核心容器,就是用于装Java Bean对象
AOP:切面编程
Aspects:提供了与AspectJ的集成
Data access:数据访问。用于访问操作我们的数据库。支持持久层的操作。jdbcTemplate mybatis
Web:用于支持数据展示层,支持http请求
Transactions:用于支持事物处理。用于解决业务层的事物处理问题。 编程式事务管理和声明式事务管理.
二.控制反转
1.概念:什么是IOC
控制反转,把原理new对象的这种方式转换成了,spring通过反射创建对象的方式, spring创建完的对象放到一个容器中,谁需要就给谁注入进去. 简单说:把创建对象和管理对象的权利交给spring
2.如何来实现IOC进行创建对象和管理对象
3.控制反转的入门案例
1.准备环境
-
导入spring所需要的4个jar
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
2.需求: 创建一个UserService , 里面有一个属性username ,有一个play的方法;
接下来使用spring来创建该对象并给该对象的username属性值设置值. 最后使用junit进行测试.
实现步骤:
1.编写一个类UserService
package com.itheima.ioc;
/**
* 需求: 创建一个UserService , 里面有一个属性username ,有一个play的方法;
* 接下来使用spring来创建改对象并给该对象的username属性值设置值. 最后使用junit进行测试.
*
* 实现步骤:
* 1.pom.xml中到如jar
* 2.创建applicationContext.xml
* 3.创建UserService 类,提供属性username setter getter play方法
* 4.在applicationContext.xml做配置
* 5.编写测试类
* 5.1 获取spring的容器对象(加载applicationContext.xml)
* 5.2 调用getBean(id)得到UserService对象
* 5.3 调用对象的play方法 (是否调用成功username是否被初始化)
*/
public class UserService {
private String username;
public void play(){
System.out.println(username);
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}
2.编写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标签 用于创建对象, 根据我们配置的完全路径通过反射创建对象.
作用效果: UserService service = new UserSerivce();
-->
<bean id="userService" class="com.itheima.service.UserService">
<!--
property ,通过反射条用set方法,给对象的username设置属性
-->
<property name="username" value="柯正恶"></property>
</bean>
</beans>
3.编写测试类
package com.itheima.service;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* * 5.编写测试类
* 5.1 获取spring的容器对象(加载applicationContext.xml)
* 5.2 调用getBean(id)得到UserService对象
* 5.3 调用对象的play方法 (是否调用成功username是否被初始化)
*/
public class UserServiceTest {
@Test
public void play() {
//5.1 获取spring的容器对象(加载applicationContext.xml)
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//5.2 调用getBean(id)得到UserService对象
UserService userService = (UserService) context.getBean("userService");
// 5.3 调用对象的play方法 (是否调用成功username是否被初始化)
userService.play();
}
}
4.通过构造方法创建对象
1)编写一个User类, 目的是使用无参构造创建他的对象
package com.itheima.ioc;
public class User {
public User() {
System.out.println("柳岩的无参构造方法");
}
}
2)编写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">
<!--创建User对象,
bean:spring框架内部回解析bean标签,创建对象java中所有类,都认为是一个bean对象
id:创建好的对象的唯一标识,通过getBean()获取spring已经创建好的对象
class:类的完全路径名,在框架内部做反射使用.
-->
<bean id="user" class="com.itheima.ioc.User"></bean>
</beans>
3)编写测试类
package com.itheima.ioc;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
/*
* 目的:查看是否调用了无参构造方法 ?
* 问题1: 哪一行代码执行会调用无参构造方法
* ApplicationContext context 会创建对象
* UserService userService 获取spring容器中创建好的对象
*
* 问题2:如果不加强转,能够直接返回我们想要的对象
* context.getBean("userService", User.class);
*
* 问题3:
* 两种加载配置文件的方式
* 该对象制度classpath下的配置文件
* ApplicationContext context = newClassPathXmlApplicationContext("ApplicationContext");
*
*
* 加载绝对路径下的配置文件
* ApplicationContext context1 = new FileSystemXmlApplicationContext("E:\\WorkSpace\\IdeaWS\\JavaWeb\\day18_spring\\target\\classes\\ApplicationContext");
*
* */
public class UserTest {
@Test
public void testUser01(){
ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext");
// ApplicationContext context1 = new FileSystemXmlApplicationContext("E:\\WorkSpace\\IdeaWS\\JavaWeb\\day18_spring\\target\\classes\\ApplicationContext");
User user = (User) context.getBean("user");
// User user1 = context.getBean("user", User.class);
System.out.println(user);
}
5.静态工厂创建对象
1.首先会提供了一个工厂类,工厂中有提供了创建对象的方法.
/**
* 需求: 使用静态工厂的方式创建对象, 由spring配置方式创建
*
* 实现步骤:
* 1.创建工厂类
* 2.工厂类中编写一个静态方法, (返回执行类User)
* 3.applicationContext.xml中配置如何创建
* 4.测试,通过静态工厂获取对象
*/
public class UserStaticFactory {
//静态方法创建user并返回
public static User getUser(){
return new 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">
<!--
通过静态工厂获取user对象
id: 获取user类的id
class 工厂的全类名
factory-method :工厂的指定获取user的方法
-->
<bean id="user01" class="com.itheima.ioc.UserStaticFactory" factory-method="getUser"></bean>
</beans>
//1.静态工厂的测试,获取user对象
@Test
//4.测试,通过静态工厂获取对象
public void test01(){
//1.获取Context容器 ,
ApplicationContext context =
new ClassPathXmlApplicationContext("applicationContext.xml");
//2.getBean获取user对象
User user = context.getBean("user02", User.class);
//3.打印
System.out.println(user);
}
6.实例工厂创建对象
1)编写一个实例工厂,目的创建User对象
/**
* 实例工厂获取user对象
*/
public class UserFactory {
public User getUser() {
return new 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">
<!--
通过实例工厂创建user对象
3.1 先创建实例工厂对象
3.2 再创建user对象
-->
<bean id="factory" class="com.itheima.ioc.UserFactory"></bean>
<bean id="user02" factory-bean="factory" factory-method="getUser"></bean>
</beans>
/*测试使用实例工厂获取user对象*/
@Test
public void testUser03(){
ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext");
User user02 = context.getBean("user02", User.class);
System.out.println(user02);
}
7.spring创建对象的范围
问题: 每次获取对象的时候,spring是新创建一个对象还是始终给我们返回同一个对象.
单例: 内存中只有一个对象,每次获取到该对象的地址值一样.
多例:内存中的每个对象都是一个新的对象,他们的地址值都不同.
1.答案: spring默认的情况下创建的对象都是单例的. (每次返回的对象都是同一个)
测试:
<!--1.通过构造方法创建User对象
scope="singleton" 单例(默认值)
scope="prototype" 多例
scope="request" 创建的对象放到request域中
scope="session" 创建对象放到session对象
-->
<bean id="user" class="com.itheima.ioc.User" scope="singleton"></bean>
<bean id="user" class="com.itheima.ioc.User" scope="prototype"></bean>
/**
* 判断spring创建的user对象是单例还是多例
* 1.默认情况下spring创建的对象是单例的
*
* 2.想让spring创建的对象每次都不一样,创建多例对象
* 如果我们将scope="prototype" , 调用getBean的时候创建对象
*/
@Test
public void testUser04(){
//1.获取spring容器
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//2.调用getBean方法得到user
User user1 = (User) context.getBean("user");
User user2 = (User) context.getBean("user");
User user3 = (User) context.getBean("user");
System.out.println(user1);
System.out.println(user2);
System.out.println(user3);
}
8.spring创建对象的生命周期
1)spring创建的对象什么时候创建,什么时候运行,什么时候销毁.
结论:1. 配置文件加载的时候对象就创建, 2.当使用该对象的时候就运行 3.当spring的容器关闭的时候对象销毁
测试:
package com.itheima.life;
public class Student {
public void init(){
System.out.println("stu对象创建了");
}
public void service(){
System.out.println("stu对象的service方法执行了");
}
public void destroy(){
System.out.println("stu 对象销毁了.");
}
}
<?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">
<!--spring创建对象的生命周期
init-method 当该对象初始化的时候该方法会自动执行
destroy-method 当该对象即将销毁的时候会自动调用该方法
-->
<bean id="stu" class="com.itheima.life.Student" init-method="init" destroy-method="destroy"></bean>
</beans>
package com.itheima.life;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import static org.junit.Assert.*;
public class StudentTest {
//测试student的生命周期
/**
* 1.debug执行查看结果
* 2.执行到哪一个行init方法会执行 21
* 3.执行到哪一行service方法执行 23
* 4.执行到哪一个行destroy执行 容器关闭 close() ClassPathXmlApplicationContext
*/
@Test
public void testLife(){
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
Student stu = context.getBean("stu", Student.class);
stu.service();
context.close(); //容器关闭
}
}
三.依赖注入
1.概念
DI (dependency injection) 依赖注入
含义:就是给对象的属性设置值.
原来给对象的属性设置值: set方法给对象设置值 构造方法给对象初始化的时候设置值.
2.set方式设置属性
前提条件类中必须有set方法
首先创建Person类
package com.itheima.ioc;
import java.util.Date;
/**
* 需求:使用set方式给person的属性注入值
* <p>
* 1.创建属性,并提供set方法
* 2.spring配置文件中,先创建对象<bean id class> <property name="" value=""> </bean>
* 3.测试,获取对象,打印对象的属性
*/
public class Person {
private String name;
private Date birthday;
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", birthday=" + birthday +
'}';
}
}
<?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">
<!--使用spring创建一个日期-->
<bean id="datee" class="java.util.Date"></bean>
<bean id="person" class="com.itheima.ioc.Person">
<!--
name : 代表的是set方法去掉set,首字母小写
value: 基本类型或字符串类型的值,具体给属性设置用的
ref (引用) : 引用对象的id,作为一个对象类型注入
-->
<property name="name" value="wenboao"></property>
<property name="birthday" ref="datee"></property>
</bean>
</beans>
/**
* 测试目标: 获取person对象,查看person的属性是否有值. 通过set注入
*
* 注意事项: spring配置文件中 , name属性是set方法去掉set首字母小写 <property name="name" value="柳岩"></property>
*/
@Test
public void a(){
ApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml");
Person person = context.getBean("person", Person.class);
System.out.println(person);
}
3.构造方式注入
前提条件类中必须有有参构造方法
1.编写Person类
package com.itheima.ioc;
import java.util.Date;
/**
* 必须提供有参构造方法
*/
public class Person1 {
private String name;
private Date birthday;
public Person1() {
}
public Person1(String name, Date birthday) {
this.name = name;
this.birthday = birthday;
}
@Override
public String toString() {
return "Person1{" +
", name='" + name + '\'' +
", birthday=" + birthday +
'}';
}
}
<?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">
<!--使用spring创建一个日期-->
<bean id="datee" class="java.util.Date"></bean>
<!--采用构造方法创建对象-->
<bean id="person1" class="com.itheima.ioc.Person1">
<!--
constructor-arg 构造方法注入
name 代表的构造方法上的属性名称
value 代表传递的属性值(基本+String)
ref 注入的是引用类型
-->
<constructor-arg name="name" value="wenboao"/>
<constructor-arg name="birthday" ref="datee"/>
</bean>
</beans>
@Test
public void testPerson02(){
ApplicationContext context =
new ClassPathXmlApplicationContext("personbean.xml");
Person person = context.getBean("person02", Person1.class);
System.out.println(person);
}
4.p名称空间注入和c名称空间注入
P代表propertory 属性, 是set注入的简化方式 (提供set方法)
C代表Constructor 构造注入的简化方式 (提供构造方法)
实现步骤
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
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="birthday" class="java.util.Date"></bean>
<!--使用p名称空间注入属性-->
<bean id="person_p" class="com.itheima.di.Person" p:id="3" p:userName="杨过" p:age="22" p:birthday-ref="birthday"/>
<!--使用c名称空间注入-->
<bean id="person_c" class="com.itheima.di.Person" c:id="3" c:name="雕" c:age="220" c:birthday-ref="birthday"/>
</beans>
5.复杂数据类型注入
我们的类中属性Aarry 数组 List 集合 Map集合 Set集合 Properties集合,如何给这些属性设置值.
package com.itheima.listmap;
import com.itheima.ioc.Person;
import java.util.*;
/**
* 采用的是set方式注入
*/
public class ComplexBean {
private String[] arr;
private List<Person> list;
private Set<String> set;
private Map<String, Person> map;
private Properties properties;
public String[] getArr() {
return arr;
}
public void setArr(String[] arr) {
this.arr = arr;
}
public List<Person> getList() {
return list;
}
public void setList(List<Person> list) {
this.list = list;
}
public Set<String> getSet() {
return set;
}
public void setSet(Set<String> set) {
this.set = set;
}
public Map<String, Person> getMap() {
return map;
}
public void setMap(Map<String, Person> map) {
this.map = map;
}
public Properties getProperties() {
return properties;
}
public void setProperties(Properties properties) {
this.properties = properties;
}
@Override
public String toString() {
return "ComplexBean{" +
"arr=" + Arrays.toString(arr) +
", list=" + list +
", set=" + set +
", map=" + map +
", properties=" + properties +
'}';
}
}
配置文件
<!--注入复杂数据类型-->
<bean id="complexBean" class="com.itheima.di.ComplexBean">
<!--1.先注入数组-->
<property name="arr">
<array>
<value>柯镇恶</value>
<value>郭靖</value>
<value>杨过</value>
</array>
</property>
<!--2.注入list类型-->
<property name="list">
<list>
<ref bean="person" />
<ref bean="person02" />
<ref bean="person_p" />
</list>
</property>
<!--3.注入set集合-->
<property name="set">
<set>
<value>乔峰</value>
<value>段誉</value>
<value>虚竹</value>
</set>
</property>
<!--4.注入map-->
<property name="map">
<map>
<entry key="志平" value-ref="person"/>
<entry key="小龙女" value-ref="person02"/>
<entry key="杨过" value-ref="person_p"/>
</map>
</property>
<!--5.注入properties-->
<property name="properties">
<props>
<prop key="no1">石破天</prop>
<prop key="no2">虚竹</prop>
<prop key="no3">张无忌</prop>
</props>
</property>
</bean>
public class ComplexBeanTest {
@Test
public void testComplexBean(){
ApplicationContext context =
new ClassPathXmlApplicationContext("personbean.xml");
ComplexBean complexBean = context.getBean("complexBean", ComplexBean.class);
String[] arr = complexBean.getArr();
System.out.println(Arrays.toString(arr));
System.out.println("---------------------");
List<Person> list = complexBean.getList();
for (Person person : list) {
System.out.println(person);
}
System.out.println("---------------------");
Set<String> set = complexBean.getSet();
System.out.println(set);
System.out.println("---------------------");
Map<String, Person> map = complexBean.getMap();
Set<Map.Entry<String, Person>> entrySet = map.entrySet();
for (Map.Entry<String, Person> entry : entrySet) {
System.out.println(entry.getKey()+ " "+ entry.getValue());
}
System.out.println("---------------------");
Properties properties = complexBean.getProperties();
System.out.println(properties);
}
}
四.注解方式的IOC和DI
1.使用注解方式创建对象
要求:
1.需要导入一个aop.jar的jar ,该包已经被spring-context.jar依赖引入了.不需要再导入
2.在配置文件中需要进行一个包扫描的配置
需求:创建一个UserService接口,创建他的实现类UserServiceImpl 编写一个方法 findUser方法
在测试类中采用注解的方式获取到该实现类对象并调用他的方法.
目的:掌握注解方式创建对象
annotationBean.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"
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/context/spring-context.xsd">
<!--
使用注解方式进行创建对象
1.开启注解扫描
含义:开启注解扫描,指定了 base-package 扫描指定的包,扫描包中所有的类
查看类上是否有指定的注解, 如果类上有指定的注解,那么就创建该类对象,
放到spring容器中
-->
<context:component-scan base-package="com.itheima.annotation"/>
</beans>
public interface UserService {
public void addUser();
}
/**
* 需求:
* 1. 使用注解方式创建UserService的实现类对象,并调用其方法测试
*
* 实现的步骤:
* 1.要在spring配置文件 bean2.xml 中进行注解扫描
* 2.要给实现类上添加指定的注解,让spring扫描
* 3.编写测试,获取对象,调用方法
*/
/**
* IOC注入的注意事项:
* 1.bean id 我们可以自己设置 @Component("abc") ===> <bean id="abc" class="com.itheima.annotation.UserServiceImpl">
*
* 2.相关的注解还有4个 , 他们的作用都是用来创建对象,功能一样.
* @Component 如果不确定是那一层,统统使用该注解
* @Repository 建议在数据访问层 dao层的实现类上使用
* @Service 建议在service层使用
* @Controller 建议在表现层使用 在springMVC中只能使用它
*/
//Component注解就会被spring扫描到,相当于<bean id="userServiceImpl" class="com.itheima.annotation.UserServiceImpl"/>
@Component("abc")
public class UserServiceImpl implements UserService{
public void addUser() {
System.out.println("UserServiceImpl--->addUser 执行了");
}
}
@Test
public void c(){
ApplicationContext context = new ClassPathXmlApplicationContext("bean3.xml");
UserService abc = context.getBean("abc", UserService.class);
abc.addUser();
}
2.使用注解方式注入
在Service中使用注解的方式注入Dao对象
第一种注入方式
UserDao接口及其实现类
public interface UserDao {
public void daoAddUser();
}
import org.springframework.stereotype.Repository;
@Repository
public class UserDaoImpl implements UserDao {
public void daoAddUser() {
System.out.println("UserDaoImpl 的 daoAddUser方法执行了");
}
}
UserService接口及其实现类
public interface UserService {
public void addUser();
}
package com.itheima.annotation;
@Service("abc")
public class UserServiceImpl implements UserService {
/*
* @Autowired 会自动根据UserDao的类型,在spring容器中查找UserDao的实现类
* 将实现类赋值给成员变量dao
* */
//!!!问题:如果该父类有两个子类 UserDao的子类 UserDaoImpl UserDaoImpl02
//无法确定使用哪一个,我们需要添加一个注解来确定注入哪一个
/**
* 第一种注入方式:
* 注入UserDao的实现类
* @Autowired 自动注入,写在类的成员变量上, 可以根据UserDao接口,创建该接口的实现类,在自动的设置到该成员变量上
*/
@Autowired
@Qualifier("userDaoImpl") //设置子类的bean id 来确定注入的是哪个子类对象
private UserDao dao;
public void addUser() {
System.out.println("UserServiceImpl--->addUser 执行了");
dao.daoAddUser();
}
}
@Test
public void c(){
ApplicationContext context = new ClassPathXmlApplicationContext("bean3.xml");
UserService abc = context.getBean("abc", UserService.class);
abc.addUser();
}
/*
测试结果:
UserServiceImpl--->addUser 执行了
UserDaoImpl 的 daoAddUser方法执行了
*/
第二种注入方式
/**
* 第二种注入方式:
* @Value("#{bean的id}")
*/
@Value("#{userDaoImpl02}")
private UserDao dao;
@Value("柳岩")
private String name;
第三种注入方式
/**
* 第三种注入方式 : 是jdk的注解不是spring
* @Resource(name="bean的id值")
*/
@Resource(name="userDaoImpl")
private UserDao dao;