Spring的IOC的注解开发(案例+解析)

Spring 开发的时候可以配置XML也可以用注解开发,

一般情况下使用XML的较多

注解开发的优点就是方便,无论是将类交给Spring管理还是属性注入,都可以直接在当前类上或者方法上,或者属性上,添加注解就可以直接使用,就可以完成类的管理和属性注入

XML的优点是逻辑清晰
两种方式各有优缺点,
在不同情况下选择不同的开发方式,
下面将介绍Spring的注解开发,以及XML和注解的混合开发的案例

一、Spring的IOC的注解开发:普通属性

1、创建一个web项目,引入jar

在这里插入图片描述

  • 在Spring4的版本注解开发的时候,除了引入基本的开发包以外,还需要引入aop的包。
    在这里插入图片描述

2、引入Spring的配置文件

(1) 在src下创建applicationContext.xml
(2) 引入约束:使用注解开发需要引入context约束。

约束路径:
spring-framework-4.2.4.RELEASE-dist\spring-framework-4.2.4.RELEASE\docs\spring-framework-reference\html\xsd-configuration.html
在这里插入图片描述
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"
    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"> 
        <!-- bean definitions here -->
</beans>

3、创建接口和实现类

package com.itzheng.spring.demo1;
public interface UserDao {
	public void save();
}
package com.itzheng.spring.demo1;
public class UserDaoImpl implements UserDao {
	@Override
	public void save() {
		// TODO Auto-generated method stub
		System.out.println("DAO保存用户的方法执行了。。。。");

	}
}
(1)传统方式
@Test
// 传统测试方法
public void demo1() {
	UserDao dao = new UserDaoImpl();
	dao.save();
}
(2)Spring的IOC的注解方式
  • a、开启Spring的组件扫描
    使用IOC的注解开发,需要配置组件扫描 component-scan 组件扫描(哪些包【包路径】下的类要使用IOC的注解)
    <context:component-scan base-package="com.itzheng.spring.demo1"></context:component-scan>
<?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"> 
        <!-- bean definitions here -->    
        <!-- Spring的IOC注解的入门 -->
        <!-- 使用IOC的注解开发,需要配置组件扫描  component-scan 组件扫描(哪些包【包路径】下的类要使用IOC的注解) -->
        <context:component-scan base-package="com.itzheng.spring.demo1"></context:component-scan>		
</beans>
  • b、在类上添加注解
    在要实例化的类上添加注解
    用户DAO实现类,要在要实现的类上添加注解
    @Component(value = "userDao") // 或者将value省略
    相当于在xml 当中配置<bean id="userDao" class="com.itzheng.spring.demo1.UserDaoImpl"/>
package com.itzheng.spring.demo1;
import org.springframework.stereotype.Component;
//用户DAO实现类,要在要实现的类上添加注解
@Component(value = "userDao") // 或者将value省略 相当于在xml 当中配置<bean id="userDao" class="com.itzheng.spring.demo1.UserDaoImpl"/>
public class UserDaoImpl implements UserDao {
	@Override
	public void save() {
		// TODO Auto-generated method stub
		System.out.println("DAO保存用户的方法执行了。。。。");
	}
}
  • c、编写测试类
    (UserDao) applicationContext.getBean("userDao"); 是通过注解获取到UserDaoImpl的实例对象,通过然后通过多态调用对应的方法
    getBean获取Spring当中管理的类
@Test
	//Spring的IOC的注解方式
	public void demo2() {
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		// (UserDao) applicationContext.getBean("userDao"); 获取到的是UserDaoImpl
		UserDao userDao = (UserDao) applicationContext.getBean("userDao");
		userDao.save();
	}

4、通过注解方式对实现类进行属性设置

设置属性和值

package com.itzheng.spring.demo1;
import org.springframework.stereotype.Component;
public class UserDaoImpl implements UserDao {
	private String name;
	public void setName(String name) {
		this.name = name;
	}
	@Override
	public void save() {
		// TODO Auto-generated method stub
		System.out.println("DAOImpl保存用户的方法执行了。。。。"+name);
	}
}
(1)传统方式设置值
@Test
	// 传统测试方法
public void demo1() {
	UserDaoImpl dao = new UserDaoImpl();
	dao.setName("张三");
	dao.save();
}
(2)Spring的IOC的注解方式设置值设置属性和值

用户DAO接口的实现类上添加注解,也就是在Impl的类上添加注解

@Component(value = "userDao") 或者将value省略 @Component( "userDao")
相当于在xml 当中配置<bean id="userDao" class="com.itzheng.spring.demo1.UserDaoImpl"/>

也就是工厂可以通过userDao获取到对应的UserDaoImpl对象

注解方式:
使用注解方式,在实现类当中是可以没有set方法的。

两种情况

  • a、属性如果提供set方法就将注解加在set方法上
package com.itzheng.spring.demo1;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
//用户DAODM实现类,要在要实现的类上添加注解
@Component(value = "userDao") // 或者将value省略 相当于在xml 当中配置<bean id="userDao"
								// class="com.itzheng.spring.demo1.UserDaoImpl"/>
public class UserDaoImpl implements UserDao {
	
	private String name;
	@Value("李四")
	public void setName(String name) { 
	this.name = name; 
	}
	@Override
	public void save() {
		// TODO Auto-generated method stub
		System.out.println("DAOImpl保存用户的方法执行了。。。。"+name);
	}
}
  • b、属性如果不提供set方法就将注解加在属性上
package com.itzheng.spring.demo1;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
//用户DAODM实现类,要在要实现的类上添加注解
@Component(value = "userDao") // 或者将value省略 相当于在xml 当中配置<bean id="userDao" class="com.itzheng.spring.demo1.UserDaoImpl"/>
public class UserDaoImpl implements UserDao {
	@Value("李四")
	private String name;
	@Override
	public void save() {
		// TODO Auto-generated method stub
		System.out.println("DAOImpl保存用户的方法执行了。。。。"+name);
	}
}
  • c、测试以上两种赋值的效果相同
@Test
//Spring的IOC的注解方式
public void demo2() {
	ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
	// (UserDao) applicationContext.getBean("userDao"); 获取到的是UserDaoImpl
	UserDao userDao = (UserDao) applicationContext.getBean("userDao");
	userDao.save();
}

在这里插入图片描述

二、Spring的IOC的注解开发:注解详解+属性注入

1、@Component:组件

修饰一个类,将这个类交给Spring管理。

这个注解有三个延伸注解(功能类似),用来修饰类的

(1)@Controller:修饰web层的类:
(2)@Service:修饰service层的类:
(3)@Repository:修饰dao层的类:
@Repository是将UserDaoImpl 配置,
工厂可以通过userDao来获取对应的UserDaoImpl 对象的实例,
其他两个作用一样只是修饰的类的层不同

package com.itzheng.spring.demo1;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
//用户DAO实现类,要在要实现的类上添加注解
@Repository("userDao")
public class UserDaoImpl implements UserDao {
	@Value("李四")
	private String name;
	/*
	 * public void setName(String name) { this.name = name; }
	 */
	@Override
	public void save() {
		// TODO Auto-generated method stub
		System.out.println("DAOImpl保存用户的方法执行了。。。。" + name);
	}
}

2、属性注入的注解

(1)普通属性

@Value:设置普通属性的值。

(2)对象类型的属性:@Autoware:设置对象类型的属性的值,但是它是按照类型来完成的属性注入。
package com.itzheng.spring.demo1;
public interface UserDao {
	public void save();
}

@Value(“李四”)将属性注入到UserDaoImpl 的name当中

package com.itzheng.spring.demo1;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
@Repository("userDao")//
public class UserDaoImpl implements UserDao {
	@Value("李四")
	private String name;

	@Override
	public void save() {
		// TODO Auto-generated method stub
		System.out.println("DAOImpl保存用户的方法执行了。。。。" + name);
	}
}

创建UserService

package com.itzheng.spring.demo1;
public interface UserService {
	public void save();
}

@Service(“UserService”)
// 相当于配置了<bean id="userService" class="com.itzheng.spring.demo1.UserServiceImpl">
在工厂当中通过UserService获取到UserServiceImpl对象的实例

在Service当中调用Dao层,通过注解的方式将Dao注入
UserServiceImpl

@Autowired修饰属性,将属性对应的类,注入到当前类当中

package com.itzheng.spring.demo1;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service("UserService") // 相当于配置了<bean id="userService"
						// class="com.itzheng.spring.demo1.UserServiceImpl">
public class UserServiceImpl implements UserService {
	// 注入DAO
	@Autowired
	private UserDao userDao;
	//在Service当中调用Dao层
	@Override
	public void save() {
		// TODO Auto-generated method stub
		System.out.println("UserServiceImpl执行了");
		userDao.save();
	}
}

测试

@Test
	// Spring的IOC的注解方式
	public void demo3() {
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		// (UserDao) applicationContext.getBean("userDao"); 获取到的是UserDaoImpl
		UserService userService = (UserService) applicationContext.getBean("UserService");
		userService.save();
	}

在这里插入图片描述

(3)注意

@Autoware将@Repository修饰的类注入到当前修饰的对象上,
在这里插入图片描述

因为这里是继承了UserDao所以,

@Repository修饰的名称不管是什么,

在UserServiceImpl当中的@Autoware修饰的userDao,注入的一定是UserDao的对象的实例,也就是userDaoImpl对象

但是在UserDaoImpl上一定要用@Repository来修饰该类

(4)我们的习惯是安装名称完成属性的注入:必须让@Autowired注解和@Qualifier(value="")一起使用来完成安装名称的属性注入

@Qualifier(value=“userDao”)强制按名称来完成属性的注入

@Service("UserService") // 相当于配置了<bean id="userService"  class="com.itzheng.spring.demo1.UserServiceImpl">
public class UserServiceImpl implements UserService {
	// 注入DAO
	@Autowired
	@Qualifier(value="userDao")//强制按名称来完成属性的注入
	private UserDao userDao;
	//在Service当中调用Dao层
	@Override
	public void save() {
		// TODO Auto-generated method stub
		System.out.println("UserServiceImpl执行了");
		userDao.save();
	}
}
(5)@Resource:完成对象类型的属性的注入,按照名称完成属性注入。
@Service("UserService") // 相当于配置了<bean id="userService"
						// class="com.itzheng.spring.demo1.UserServiceImpl">
public class UserServiceImpl implements UserService {
	// 注入DAO
	@Resource(name = "userDao")
	private UserDao userDao;
	// 在Service当中调用Dao层
	@Override
	public void save() {
		System.out.println("UserServiceImpl执行了");
		userDao.save();
	}
}

注解可以理解为拆分版的XML和XML的原理相同,所有的注解可以理解为在同一个XML下的配置

三、Bean的其他的注解

1、生命周期的注解:对类进行初始化的注解(在对应初始化方法上进行注解)

通过设置@Service(“customerService”) 修饰一个类,将这个类交给Spring管理。

@PostConstruct :初始化方法 相当于init-method,在工厂获得Spring管理的对象,自动执行其对应的初始化方法

@PreDestroy : 销毁方法 相当于destroy-method=“destroy”,在工厂获得Spring管理的对象,自动执行其对应的销毁方法

package com.itzheng.spring.demo2;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import org.springframework.stereotype.Service;
@Service("customerService")//<bean id="" class="" init-method="init" destroy-method="destroy"> 
public class CustomerService {
	@PostConstruct   //相当于init-method,在工厂获得Spring管理的对象,自动执行其对应的初始化方法
	public void init() {
		System.out.println("CustomerService被初始化了。。。。。");
	}
	public void save() {
		System.out.println("Service的save的方法执行。。。。。");
	}
	@PreDestroy  //相当于destroy-method="destroy",在工厂获得Spring管理的对象,自动执行其对应的销毁方法
	public void destroy() {
		System.out.println("CustomerService被销毁了。。。。。");
	}
}

测试类

package com.itzheng.spring.demo2;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpringDemo2 {
	@Test
	public void demo1() {
		//通过工厂获取xml文件
		ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		//getBean获取Spring当中管理的类
		CustomerService customerService = (CustomerService)applicationContext.getBean("customerService");
		System.out.println(customerService);
		applicationContext.close();//关闭工厂
	}
}

在这里插入图片描述

2、Bean作用的注解范围

@Scope:作用范围
Scope的取值:
singleton:默认单例
prototype:多例
request:
session:
globalsession:

(1)在customerService上设置@Scope注解

在这里插入图片描述
在测试类当中创建两个CustomerService 实例对象

public class SpringDemo2 {
	@Test
	public void demo1() {
		// 通过工厂获取xml文件
		ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(
				"applicationContext.xml");
		// getBean获取Spring当中管理的类
		CustomerService customerService1 = (CustomerService) applicationContext.getBean("customerService");
		System.out.println(customerService1);
		CustomerService customerService2 = (CustomerService) applicationContext.getBean("customerService");
		System.out.println(customerService2);
		applicationContext.close();// 关闭工厂
	}
}

结果证明两个类是同一个对象,也就是说明Scope的取值默认单例
在这里插入图片描述

(2)当@Scope(“singleton”)设置该对象交给Spring的时候是单例创建对象

在这里插入图片描述
结果和默认值想效果相同
在这里插入图片描述

(3)当@Scope(“prototype”)设置该对象交给Spring的时候是多例创建对象

在这里插入图片描述
证明创建的是两个对象,即为多例模式
在这里插入图片描述

四、IOC的XML和注解开发比较

1、XML和注解的比较

适用场景

XML:可以适用任何场景。
结构清晰,维护方便。

注解:有些地方用不了,(这个类不是自己提供的,原码当中提的属性)
纯注解(SSH)

开发方便。(编写类,在类上加注解,将类交给Spring管理,在其他地方通过工厂获得该类、属性注入直接在已经交给Spring管理的类当中,通过标签将属性注入到对应定义标签修饰的属性当中)

五、XML和注解开发的整合

1、XML管理Bean、注解完成属性注入。(在有扫描器的情况下)

编写ProductDao 类

package com.itzheng.spring.demo3;
public class ProductDao {
public void save() {
		System.out.println("ProductDao的save方法执行了。。。。");
	}
}

编写OrderDao

package com.itzheng.spring.demo3;
public class OrderDao {
	public void save() {
		System.out.println("OrderDao的save方法执行了。。。。");
	}
}

编写ProductService方法并且设置对应的属性

package com.itzheng.spring.demo3;
public class ProductService {
	private ProductDao productDao;
	private OrderDao orderDao;
	public void setProductDao(ProductDao productDao) {
		this.productDao = productDao;
	}
	public void setOrderDao(OrderDao orderDao) {
		this.orderDao = orderDao;
	}
	public void save() {
		System.out.println("ProductService的save方法执行了。。。。。");
		productDao.save();
		orderDao.save();
	}
}

将三个类交给Spring管理,productDao和orderDao并将注入到productService类当中

<?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">
	<!-- bean definitions here -->
	<!-- Spring的IOC注解的入门 -->
	<!-- 扫描是为了扫描类上的注解 -->
	<!-- 使用IOC的注解开发,需要配置组件扫描 component-scan 组件扫描(哪些包【包路径】下的类要使用IOC的注解) -->
	<context:component-scan
		base-package="com.itzheng.spring"></context:component-scan>
	<bean id="productService" class="com.itzheng.spring.demo3.ProductService">
		<property name="productDao" ref="productDao"></property>
		<property name="orderDao" ref="orderDao"></property>
	</bean>
	<bean id="productDao" class="com.itzheng.spring.demo3.ProductDao">
	</bean>
	<bean id="orderDao" class="com.itzheng.spring.demo3.OrderDao">
	</bean>
</beans>

编写测试类

package com.itzheng.spring.demo3;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpringDemo3 {
	@Test
	public void demo1() {
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		ProductService productService = (ProductService) applicationContext.getBean("productService");
		productService.save();
	}
}

在这里插入图片描述

2、使用XML和注解整合的方式(类的管理通过XML的方式,属性注入通过注解的方式) 没有扫描器的情况下(类上没有注解)

通过注解注入属性则不需要,提供set方法

并且设置context:annotation会自动根据需要注入的类当中注解,进行属性的注入

<context:annotation-config></context:annotation-config>

自动将对应类交给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/context/spring-context.xsd">
	<!-- bean definitions here -->
	<!-- Spring的IOC注解的入门 -->
	<!-- 使用IOC的注解开发,需要配置组件扫描 component-scan 组件扫描(哪些包【包路径】下的类要使用IOC的注解) -->
	<!-- 在沒有扫描的情况下,使用属性注入的注解   @Resource,@Value,@Autowired,@Qulifier-->
	<context:annotation-config></context:annotation-config>
	<bean id="productService" class="com.itzheng.spring.demo3.ProductService"></bean>
	<bean id="productDao" class="com.itzheng.spring.demo3.ProductDao"> </bean>
	<bean id="orderDao" class="com.itzheng.spring.demo3.OrderDao"> </bean>
</beans>

在@Resource上设置注入的属性
在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_44757034/article/details/107152027