「2020最新」Spring最易学习教程—第一个Spring程序
1 Spring简介
Spring 是一款轻量级的JavaEE开发框架,其对比的EJB是Sun官方力推的JavaEE解决方案。使用EJB编码必须要实现EJB的组件,必须运行在支持EJB的服务器中,无论是测试还是运行都十分不便。Spring能够非侵入的解决JavaEE的通用问题,在测试、运行、扩展等方面比EJB强大的多。
Spring构建于众多优秀的设计模式之上:工厂设计模式、代理设计模式、模板方法设计模式、策略设计模式...
设计模式:前人总结好的,用于解决特定问题的方案。
学习Spring的核心就是学习其应用的设计模式本身要解决那些问题。
2 工厂设计模式
工厂设计模式:使用工厂创建对象,代替new创建对象。
new模式的问题:
new模式下,类和类之间是强耦合的。
解决方案:工厂设计模式(解耦合)
配置一个properties文件
userService=com.bcl.service.impl.UserServiceImpl
创建BeanFactory工厂类
public class BeanFactory {
private static Properties prop = new Properties();
static{
//通过流读取配置文件,保存到prop
InputStream in = BeanFactory.class.getResourceAsStream("/applicationContext.properties");
try {
prop.load(in);
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
}finally{
if(in != null){
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public static Object getBean(String id){
//获取类对象
Object o = null;
try {
Class c = Class.forName(prop.getProperty(id));
o = c.newInstance();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
//创建对象
return o;
}
}面向接口编程
UserService service = (UserService) BeanFactory.getBean("userService");
工厂设计模式的特点:配置文件+反射+面向接口编程
通过工厂模式,解开了类和类之间强耦合,提高了程序的可维护性和可扩展性,满足开闭原则。
3 第1个Spring程序
Spring框架的基本作用:对象工厂(容器)。可以借助Spring工厂创建(获取)对象,解开类和类之间的耦合,提高程序的维护性和扩展性。
3.1 Spring工厂的使用步骤
导入依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.26.RELEASE</version>
</dependency>导入配置文件
applicationContext.xml位置任意,建议放置在resources根目录下。
<bean id="标识" class="全类名"/>
创建Spring工厂,获取对象
Spring中工厂类型:ApplicationContext(接口)
实现类:
非web环境: ClassPathXmlApplicationContext
web环境: XmlWebApplicationContext
方法:
Object getBean(String id);
3.2 Spring工厂实战
创建一个业务类
配置applicationContext.xml
<bean id="userService" class="com.bcl.service.impl.UserServiceImpl"/>
创建Spring工厂,获取对象
//创建Spring工厂
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
//从工厂中获取UserService
UserService userService = (UserService)applicationContext.getBean("userService");
userService.deleteUserById(1);
4 Spring框架的组成模块
Test:简化Spring代码的测试 核心容器:Spring作为对象工厂的实现 AOP和Aspects:面向切面编程,非侵入的为现有代码提供增强功能 辅助功能 数据访问:提供了访问数据库的功能 Web模块:提供了对Web开发的支持
Spring提供了一套完整的企业应用开发方案,同时还能和其它框架整合(Struts2、MyBatis)。在发展中,Spring族系涌现出一系列的优秀的子框架,最终发展成一个开发生态。Spring族系有名的框架:SpringMVC、SpringBoot、SpringCloud、SpringData、SpringSecurity、SpringTask...
5 Spring工厂实现原理
Spring工厂创建对象:读取配置文件(applicationContext.xml),获取到全类名,通过反射默认调用无参构造方法创建对象。
bean标签的scope属性设置对象是否单例:
singleton (单例 默认值)
prototype (多例)
为什么单例是默认策略?节省内存空间
可以被用户公用的对象(单例):
Dao、service、SqlSessionFactory
不能被用户公用的对象(多例):
connection、sqlSession、Cart、Action
6 注入(Injection)
给对象的属性赋值(注入值)。
6.1 Set注入
本质:通过无参构造方法创建对象后,调用对象属性的set方法进行赋值。
操作:在bean标签中,通过property子标签为对象的属性进行set注入。
6.1.1 基本类型(包装类)+String
<bean id="s" class="com.bcl.entity.Student">
<!-- name属性:对象的属性名
value子标签体:对象的属性值
-->
<property name="id">
<value>1</value>
</property>
<property name="name">
<value>xiaohei</value>
</property>
<property name="age">
<value>18</value>
</property>
<property name="score">
<value>100.0</value>
</property>
</bean>
<bean id="s" class="com.bcl.entity.Student">
<!-- name属性:对象的属性名
value属性:对象的属性值
-->
<property name="id" value="1"/>
<property name="name" value="xiaohei"/>
<property name="age" value="18"/>
<property name="score" value="100.0"/>
</bean>
6.1.2 自定义对象类型
<bean id="a" class="com.bcl.entity.Address">
<property name="city" value="郑州"/>
<property name="street" value="文化路"/>
</bean>
<bean id="p" class="com.bcl.entity.Person">
<property name="addr">
<!--
ref标签的bean属性:另外一个bean的id值
-->
<ref bean="a"/>
</property>
<property name="id" value="1"/>
<property name="personName" value="xiaohei"/>
</bean>
<bean id="p" class="com.bcl.entity.Person">
<!--
ref属性:另外一个bean的id值
-->
<property name="addr" ref="a"/>
<property name="id" value="1"/>
<property name="personName" value="xiaohei"/>
</bean>
6.1.3 数组、List和Set
<bean id="u" class="com.bcl.entity.User">
<property name="id" value="1"/>
<property name="name" value="xiaohei"/>
<property name="os">
<!--
array标签表示一个数组
元素是简单数据用value子标签
元素是自定义类型数据用ref子标签
-->
<array>
<value>1</value>
<value>100.0</value>
<value>hhh</value>
<ref bean="a"/>
</array>
</property>
<property name="list">
<!--
list标签表示一个List集合
元素是简单数据用value子标签
元素是自定义类型数据用ref子标签
-->
<list>
<value>1</value>
<value>hhh</value>
<ref bean="a"/>
<ref bean="a2"/>
</list>
</property>
<property name="set">
<!--
set标签表示一个Set集合
元素是简单数据用value子标签
元素是自定义类型数据用ref子标签
-->
<set>
<value>1</value>
<value>1</value>
<value>hhh</value>
<ref bean="a"/>
<ref bean="a2"/>
</set>
</property>
</bean>
6.1.4 Map和Properties
<bean id="u" class="com.bcl.entity.User">
<property name="map">
<map>
<entry key="k1"><value>v1</value></entry>
<entry key="k2" value="v2"/>
<entry key="k3" value-ref="a"/>
<entry key-ref="p" value-ref="a"/>
</map>
</property>
<property name="prop">
<props>
<prop key="pk1">pv1</prop>
<prop key="pk2">pv2</prop>
</props>
</property>
</bean>
6. 2 构造注入
本质:调用有参构造方法创建对象的同时,为属性赋值。
前提:必须要提供有参构造
操作:在bean标签中定义constructor-arg子标签。
6.2.1 基本使用
当一个类中的多个有参构造方法的参数个数不同时,constructor-arg标签会根据数量匹配构造方法进行调用
<bean id="b1" class="com.bcl.entity.Book">
<constructor-arg value="1"/>
<constructor-arg value="十万个为什么"/>
<constructor-arg value="100000.0"/>
<constructor-arg value="佚名"/>
</bean>
6.2.2 type属性
当一个类中的构造方法,形参个数相同,类型不同时,通过type属性明确形参类型,调用指定构造方法。
<bean id="b1" class="com.bcl.entity.Book">
<constructor-arg value="1" type="java.lang.Integer"/>
</bean>
6.2.3 index属性
index属性设置形参的下标,从0开始
<bean id="b1" class="com.bcl.entity.Book">
<constructor-arg value="1" type="java.lang.Integer" index="0"/>
<constructor-arg value="十万个为什么" type="java.lang.String" index="1"/>
</bean>
6.3 自动装配
本质:Spring自动分析属性,调用属性的set方法完成赋值。
操作:通过bean标签的属性 autowire = "byType"|"byName"
<bean id="bookService" class="com.bcl.service.impl.BookServiceImpl"/>
<!--<bean id="bookService2" class="com.bcl.service.impl.BookServiceImpl"/>-->
<!--
byType:根据属性的类型,在Spring容器中获取需要的对象
注意此时Spring中该类型的对象必须唯一
byName:根据属性的名字,在Spring容器找id="属性名"的对象
-->
<bean id="bookAction" class="com.bcl.action.BookAction" autowire="byType">
</bean>
「❤️ 帅气的你又来看了我」
如果你觉得这篇内容对你挺有有帮助的话:
点赞支持下吧,让更多的人也能看到这篇内容(收藏不点赞,都是耍流氓 -_-)
欢迎在留言区与我分享你的想法,也欢迎你在留言区记录你的思考过程。
觉得不错的话,也可以关注 编程鹿 的个人公众号看更多文章和讲解视频(感谢大家的鼓励与支持🌹🌹🌹)