Spring的IOC的注解开发(案例+解析)
发布日期:2021-06-29 15:02:13 浏览次数:2 分类:技术文章

本文共 11827 字,大约阅读时间需要 39 分钟。

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当中

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>
  • 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 当中配置
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 当中配置
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 当中配置
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") // 相当于配置了
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") // 相当于配置了
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") // 相当于配置了
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")//
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类当中

编写测试类

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会自动根据需要注入的类当中注解,进行属性的注入

自动将对应类交给Spring,自动将对应的属性注入到对象当中

在@Resource上设置注入的属性

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

转载地址:https://code100.blog.csdn.net/article/details/107152027 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:Spring的AOP(面向切面编程)的XML开发以及Spring的AOP的底层原理(案例+解析)
下一篇:2020年 全国大学生创业服务网,第六届 互联网+大赛报名流程(如何同意对方邀请)

发表评论

最新留言

逛到本站,mark一下
[***.202.152.39]2024年04月19日 22时19分16秒