【Spring】XML方式实现(无参构造 有参构造)和注解方式实现 IoC
文章目录
简单记录 Spring5企业级开发实战 周冠亚,黄文毅著- 和 Spring5最新完整教程IDEA版-秦疆
Spring IoC的实现方式
IoC是Spring框架的核心内容,使用多种方式完美的实现了IoC,可以使用XML配置,也可以使用注解,新版本的Spring也可以零配置实现IoC。
Spring容器在初始化时先读取配置文件,根据配置文件或元数据创建与组织对象存入容器中,程序使用时再从Ioc容器中取出需要的对象(容器中获取Bean)。
采用XML方式配置Bean的时候,Bean的定义信息是和实现分离的,而采用注解的方式可以把两者合为一体,Bean的定义信息直接以注解的形式定义在实现类中,从而达到了零配置的目的。
控制反转是一种通过描述(XML或注解)并通过第三方去生产或获取特定对象的方式。在Spring中实现控制反转的是IoC容器,其实现方法是依赖注入(Dependency Injection,DI)。
一个程序、对象创建方式、配置说明
导入Jar包
注 : spring 需要导入commons-logging进行日志记录 . 我们利用maven , 他会自动下载对应的依赖项 .
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.22.RELEASE</version>
</dependency>
https://repo.spring.io/release/org/springframework/spring/
创建一个空白maven项目实现IoC。
XML方式实现
XML方式实现用构造器方式实现IoC分为无参构造器和有参构造器两种。
通过无参构造方法来创建
User使用无参构造器的方式,实现无参构造器的IoC。
1、编写一个User实体类
User类的实现如下:
User.java
package com.test.ioc.xml;
/**
* 无参构造器实现IoC
*/
public class User {
/**
* 姓名
*/
private String name;
/**
* 无参构造器
*/
public User () {
System.out.println("user无参构造方法");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
'}';
}
/**
* 显示姓名
*/
public void showName(){
System.out.println("我叫 " + name +",哈哈!");
}
/**
* 说话的方法
*/
public void say() {
System.out.println("大家好!");
}
}
2、编写我们的spring文件
编写我们的spring文件 , 这里我们命名为spring-chapter2.xml
在resources下spring-chapter2.xml文件中,通过bean标签将User类交给IoC容器管理,代码如下:
<?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就是java对象 , 由Spring创建和管理-->
<!-- User无参构造器 -->
<bean id="user" class="com.test.ioc.xml.User">
<property name="name" value="柳小子"/>
</bean>
</beans>
3、测试类 UserTest.java
我们可以去进行测试了,哈哈
UserTest.java
package ioc.xml;
import com.test.ioc.xml.User;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @author Liu Awen Email:willowawen@gmail.com
* @create 2020-01-14 9:47 AM
*/
public class UserTest {
@Test
public void test(){
//解析beans.xml文件 , 生成管理相应的Bean对象
ApplicationContext context = new ClassPathXmlApplicationContext("spring-chapter2.xml");
//getBean : 参数即为spring配置文件中bean的id .
User user = (User) context.getBean("user");
user.say();
user.showName();
}
}
4、测试结果
D:\Environments\jdk-11.0.2\bin\java.exe...
user无参构造方法
大家好!
我叫 柳小子,哈哈!
Process finished with exit code 0
结果可以发现,在调用showName方法之前,User对象已经通过无参构造初始化了!
User使用无参构造器的方式,实现无参构造器的IoC。
OK , 到了现在 , 我们彻底不用再去程序中去改动了 , 要实现不同的操作 , 只需要在xml配置文件中进行修改 , 所谓的IoC,一句话搞定 : 对象由Spring 来创建 , 管理 , 装配 !
思考
user 对象是谁创建的 ?
【 user 对象是由Spring创建的 】
user 对象的属性是怎么设置的 ?
【user 对象的属性是由Spring容器设置的 】
这个过程就叫控制反转(IoC) :
- 控制 : 谁来控制对象的创建 , 传统应用程序的对象是由程序本身控制创建的 , 使用Spring后 , 对象是由Spring来创建的
- 反转 : 程序本身不创建对象 , 而变成被动的接收对象 .
依赖注入 : 就是利用set方法来进行注入的.
IOC是一种编程思想,由主动的编程变成被动的接收
可以通过newClassPathXmlApplicationContext去浏览一下底层源码 .
通过有参构造方法来创建
与User类不同的是,Order类是没有无参构造器的,Order类含有一个带有两个参数——订单号和订单金额的有参构造器。
1、Order.java
Order类的定义如下:
package com.test.ioc.xml;
/**
* 有参构造器实现IoC
*/
public class Order implements Deliverable {
/**
* 订单号
*/
private long orderId;
/**
* 订单金额
*/
private double amount;
/**
* 有参构造器
* @param orderId
* @param amount
*/
public Order (long orderId, double amount) {
this.orderId = orderId;
this.amount = amount;
}
public long getOrderId() {
return orderId;
}
public void setOrderId(long orderId) {
this.orderId = orderId;
}
public double getAmount() {
return amount;
}
public void setAmount(double amount) {
this.amount = amount;
}
@Override
public String toString() {
return "Order{" +
"orderId=" + orderId +
", amount=" + amount +
'}';
}
/**
* 订单发货方法
*/
@Override
public void delivery() {
System.out.printf("订单号%s,金额%s,已发货!", orderId, amount);
}
}
interface 接口 Deliverable
package com.test.ioc.xml;
public interface Deliverable {
/**
* 发货
*/
void delivery();
}
2、spring-chapter2.xml
在spring-chapter2.xml文件中通过bean标签将User类交给IoC容器管理。具体配置如下:
<?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">
<!--Order有参构造器-->
<bean id="order" class="com.test.ioc.xml.Order">
<constructor-arg index="0" value="202001141004"/>
<constructor-arg index="1" value="8888"/>
</bean>
</beans>
*.xml 有三种方式编写
<!-- 第一种根据index参数下标设置 -->
<bean id="order" class="com.test.ioc.xml.Order">
<!-- index指构造方法 , 下标从0开始 -->
<constructor-arg index="0" value="202001141004"/>
<constructor-arg index="1" value="8888"/>
</bean>
<!-- 第二种根据参数名字设置 -->
<bean id="order" class="com.test.ioc.xml.Order">
<!-- name指参数名 -->
<constructor-arg name="orderId" value="202001141004"/>
<constructor-arg name="amount" value="8888"/>
</bean>
<!-- 第三种根据参数类型设置 -->
<bean id="order" class="com.test.ioc.xml.Order>
<constructor-arg type="java.lang.Long" value="202001141004"/>
<constructor-arg type="java.lang.Double" value="8888"/> </bean>
3、测试类 OrderTest.java
在单元测试类OrderTest中,通过依赖注入得到Deliverable的对象Order,单元测试代码如下:
package ioc.xml;
import com.test.ioc.xml.Deliverable;
import com.test.ioc.xml.Speakable;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* 测试XML方式的IoC
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:spring-chapter2.xml")
public class XmlTest {
//Spring 容器注入依赖的Speakable对象
@Autowired
private Speakable speakable;
//Spring 容器注入依赖的Deliverable对象
@Autowired
private Deliverable deliverable;
@Test
public void test() {
speakable.say();
deliverable.delivery();
}
}
其中@RunWith这个注解指定了让单元测试运行于Spring的环境中,@ContextConfiguration这个注解指定Spring加载的配置文件。
4、测试结果
执行单元测试,测试结果如下。
D:\Environments\jdk-11.0.2\bin\java.exe...
订单号202001141004,金额8888.0,已发货!
Order{orderId=202001141004, amount=8888.0}
Process finished with exit code 0
结论:在配置文件加载的时候。其中管理的对象都已经初始化了!
Order使用有参构造器的方式,实现有参构造器的IoC。
通过注解方式实现
除了通过构造器实现IoC,还可以通过Spring提供的注解方法实现IoC,这也是企业开发过程中最常用的一种IoC实现方式。
1、编写一个Student实体类
下面通过学生类Student阐述注解的方式实现IoC。
接口 HomeWork.java
package com.test.ioc.annotation;
public interface HomeWork {
/**
* 写家庭作业
*/
void doHomeWork();
}
Student类的定义如下:
package com.test.ioc.annotation;
import org.springframework.stereotype.Service;
@Service
public class Student implements HomeWork {
/**
* 写家庭作业
*/
@Override
public void doHomeWork() {
System.out.println("我是学生,我要写家庭作业");
}
}
注意此时的Student类上加了一个@Service注解,这告诉Spring,让其管理这个类的对象,因此开发人员就不再需要管理Student对象了。
2、编写我们的spring文件
与XML方式实现的IoC不同的是,注解方式除了配置@Service注解外,还需要指定Spring对需要管理的bean目录,否则Spring不能定位其需要管理的bean。具体配置如下:
<!--spring 管理的bean的路径-->
<context:component-scan base-package="com.test.ioc"></context:component-scan>
spring-chapter2.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">
<!--spring 管理的bean的路径-->
<context:component-scan base-package="com.test.ioc"></context:component-scan>
</beans>
3、依赖注入,将对象注入到测试类中
接下来在测试类AnnotationTest中通过依赖注入,将HomeWork对象注入到AnnotationTest测试类中,测试代码如下:
package ioc.annotation;
import com.test.ioc.annotation.HomeWork;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.junit4.SpringRunner;
/**
* 测试注解方式的IoC
*/
@RunWith(SpringRunner.class)
@ContextConfiguration("classpath:spring-chapter2.xml")
public class AnnotationTest {
@Autowired
private HomeWork homeWork;
//Spring 容器注入依赖的Deliverable对象
@Test
public void test() {
homeWork.doHomeWork();
}
}
4、测试结果
运行单元测试,测试结果如下:
D:\Environments\jdk-11.0.2\bin\java.exe
我是学生,我要写家庭作业
Process finished with exit code 0
除了例中的注解@Service可以实现Bean的IoC以外,Spring还提供了很多其他的注解来实现IoC。
(1)@Component将Java类标记成一个Spring Bean组件。
(2)@Service将业务层实现类标记成一个Spring Bean组件。
(3)@Controller将控制层类标记成一个Spring Bean组件。
(4)@Repository将一个持久层实现类标记成一个Spring Bean组件。
Spring 配置
别名
alias 设置别名 , 为bean设置别名 , 可以设置多个别名
<!--设置别名:在获取Bean的时候可以使用别名获取-->
<alias name="user" alias="userNew"/>
Bean配置
<!--bean就是java对象,由Spring创建和管理-->
<!--
id 是bean的标识符,要唯一,如果没有配置id,name就是默认标识符
如果配置id,又配置了name,那么name是别名
name可以设置多个别名,可以用逗号,分号,空格隔开
如果不配置id和name,可以根据applicationContext.getBean(.class)获取对象;
class是bean的全限定名=包名+类名
-->
<bean id="hello" name="hello2 h2,h3;h4" class="com.kuang.pojo.Hello">
<property name="name" value="Spring"/>
</bean>
import
团队的合作通过import来实现 .
<import resource="{path}/beans.xml"/>
参考资料
1.Spring 5企业级开发实战/周冠亚,黄文毅著.—北京:清华大学出版社,2019
2.Spring:概述、IOC理论-秦疆-–https://www.bilibili.com/video/av71110355
3.Spring:第一个程序、对象创建方式、配置说明-秦疆。https://www.bilibili.com/video/av71110355
【Spring】XML方式实现(无参构造 有参构造)和注解方式实现 IoC的更多相关文章
- Spring配置文件中bean标签中init-method和destroy-method和用注解方式配置
Person类: public class Person { private int i = 0; public Person(){ System.o ...
- 【初识Spring】对象(Bean)实例化及属性注入(注解方式)
通过xml的方式进行对象的实列化或属性注入或许有一些繁琐,所以在开发中常用的方式更多是通过注解的方式实现对象实例化和属性注入的. 开始之前 1.导入相关的包(除了导入基本的包还要导入aop的包): 创 ...
- 【spring boot】14.spring boot集成mybatis,注解方式OR映射文件方式AND pagehelper分页插件【Mybatis】pagehelper分页插件分页查询无效解决方法
spring boot集成mybatis,集成使用mybatis拖沓了好久,今天终于可以补起来了. 本篇源码中,同时使用了Spring data JPA 和 Mybatis两种方式. 在使用的过程中一 ...
- spring与hibernate整合配置基于Annotation注解方式管理实务
1.配置数据源 数据库连接基本信息存放到properties文件中,因此先加载properties文件 <!-- jdbc连接信息 --> <context:property-pla ...
- Spring MVC 数据验证——validate注解方式
1.说明 学习注解方式之前,应该先学习一下编码方式的spring注入.这样便于理解验证框架的工作原理.在出错的时候,也能更好的解决这个问题.所以本次博客教程也是基于编码方式.仅仅是在原来的基础加上注解 ...
- 【核心核心】4.Spring【IOC】注解方式
1.导入jar包 2.创建对应的类 public interface HelloService { public void sayHello(); } /** * @Component(value=& ...
- 从零开始学JAVA(09)-使用SpringMVC4 + Mybatis + MySql 例子(注解方式开发)
项目需要,继续学习springmvc,这里加入Mybatis对数据库的访问,并写下一个简单的例子便于以后学习,希望对看的人有帮助.上一篇被移出博客主页,这一篇努力排版整齐,更原创,希望不要再被移出主页 ...
- SpringMVC注解方式与文件上传
目录: springmvc的注解方式 文件上传(上传图片,并显示) 一.注解 在类前面加上@Controller 表示该类是一个控制器在方法handleRequest 前面加上 @RequestMap ...
- SpringMVC 注解方式进行配置页面跳转
@ 目录 修改IndexController 修改springmvc-servlet.xml 效果 修改IndexController 在类前面加上@Controller 表示该类是一个控制器 在方法 ...
- hibernate annotation注解方式来处理映射关系
在hibernate中,通常配置对象关系映射关系有两种,一种是基于xml的方式,另一种是基于annotation的注解方式,熟话说,萝卜青菜,可有所爱,每个人都有自己喜欢的配置方式,我在试了这两种方式 ...
随机推荐
- JS复习之深浅拷贝
一.复习导论(数据类型相关) 想掌握JS的深浅拷贝,首先来回顾一下JS的数据类型,JS中数据类型分为基本数据类型和引用数据类型. 基本数据类型是指存放在栈中的简单数据段,数据大小确定,内存空间大小可以 ...
- 一、eclipse配置TestNG
eclipse配置TestNG可以通过eclipse直接下载,但我没有vpn,所以使用线下配置. 1-下载TestNG的配置文件,有两个文件 features 和 plugins 2-eclipse配 ...
- beautiful soup 遇到class标签的值中含有空格的处理
用Python写一个爬虫,用BeautifulSoup解析html.其中一个地方需要抓取下面两类标签:<dd class="ab " >blabla1</dd&g ...
- Numpy的学习4-array的合并
import numpy as np A = np.array([1, 1, 1]) B = np.array([2, 2, 2]) print(np.vstack((A, B))) # vertic ...
- 第十章 Seata--分布式事务
承接上篇 ,终于我们迎来了最后一章 第九章 Nacos Config–服务配置,第十章 Seata–分布式事务,感谢你能学习到这 !废话不多说,撸码 10.1 分布式事务基础 10.1.1 事务 事务 ...
- JPA 缓存
JPA有两种类型的缓存: EntityManager自身就是一种缓存.事务中从数据库获取的和写入到数据库的数据会被缓存(什么样的数据会被缓存,在后面有介绍).在一个程序中也许会有很多个不同的Entit ...
- PP主数据-物料主数据
一.PP物料主数据:PP的物料主数据,是对应到系统的组织架构的,不同的组织层次,都有各自的主数据需要创建. (1),一般数据:一般数据是在集团层面的主数据,主要包括:物料编码.物料描述.辅助计量单位以 ...
- Raft算法系列教程4:日志不一致的解决
网络不可能一直处于正常情况,因为Leader或者某个Follower有可能会崩溃,从而导致日志不能一直保持一致.因此存在以下三种情况: (1)Follower缺失当前Leader上存在的日志条目.(2 ...
- Thymeleaf Shiro标签
记录一下 guest标签 <shiro:guest> </shiro:guest> 用户没有身份验证时显示相应信息,即游客访问信息. user标签 <shiro:user ...
- mysql基础之double,float长度标度定义
MySQL类型float double decimal的区别 float数值类型用于表示单精度浮点数值,而double数值类型用于表示双精度浮点数值,float和double都是浮点型,而decima ...