初识Spring
初识Spring笔记整理
Spring简介
Spring是一个开放源代码的设计层面框架,它解决的是业务逻辑层和其他各层的松耦合问题,因此它将面向接口的编程思想贯穿整个系统应用。Spring是于2003年兴起的一个轻量级的Java开发框架,由Rod Johnson创建。简单来说,Spring是一个分层的JavaSE/EE full-stack(一站式)轻量级开源框架。
Spring是一个非常活跃的开源框架,基于ICO和AOP来构架多层JavaEE系统,以帮助分离项目组件之间的依赖关系。他的主要目的是简化企业开发。
简单来说,Spring是一个分层的JavaSE/EE full-stack(一站式)轻量级开源框架。高内聚低耦合!!!
Spring 春天、泉水! JAVAEE的春天来了!
Spring官网:https://spring.io/
Spring作用
- -IOC思想 方便解耦,简化开发:Spring就是一个大工厂,可以将所有对象创建和依赖的关系维护,交给Spring容器管理!
- -AOP编程(面向切面编程)的支持:Spring提供面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等功能!
- -声明式事务的支持:只需要通过配置就可以完成对事务的管理,而无需手动编程 SSM、SSS、SSH。
- -方便程序的测试:Spring对Junit4支持,可以通过注解方便的测试Spring程序
Spring-test:Spring 的测试模块! - -方便集成各种优秀框架:Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀框架的直接支持(如:Struts、Hibernate、MyBatis、Quartz(定时任务)等)的直接支持。
Spring框架可以无缝缝合整合其他框架:Mybatis、Hibernate、Redis、Activiti、SpringMVC、SpringDATA…
只要是框架,那么Spring就可以管理! - -降低JavaEE API的使用难度:Spring对JavaEE开发中非常难用的一些API(JDBC、JavaMail、远程调用等),都提供了封装,使这些API应用难度大大降低。
Spring体系结构
Spring 框架采用分层架构,根据不同的功能被划分成了多个模块,这些模块大体可分为 Data Access/Integration(数据访问/集成层) 、Web、AOP(Aspect Oriented Programming) 、Aspects、Messaging、Instrumentation(植入模块)、Core Container(核心容器) 和 Test(测试模块)。
core - 核心模块
- spring-core:依赖注入IoC与DI的最基本实现
- spring-beans:Bean工厂与bean的装配
- spring-context:spring的context上下文即IoC容器
- spring-context-support
- spring-expression:spring表达式语言
Spring之IOC
依赖注入或控制反转的定义中,调用者不负责被调用者的实例创建工作,该工作由Spring 框架中的容器来负责,它通过开发者的配置来判断实例类型,创建后再注入调用者。由于Spring容器负责被调用者实例,实例创建后又负责将该实例注入调用者,因此称为依赖注入。而被调用者的实例创建工作不再由调用者来创建而是由Spring来创建,控制权由应用代码转移到了外部容器,控制权发生了反转,因此称为控制反转。
1.lOC控制反转
lOC-Inversion of Control,即控制反转。它不是什么技术,而是一种设计思想。
传统的创建对象的方法是直接通过new关键字,而spring 则是通过IOC容器来创建对象,也就是说我们将创建对象的控制权交给了IOC容器。我们可以用一句话来概括IOC:IOC让程序员不在关注怎么去创建对象,而是关注与对象创建之后的操作,把对象的创建、初始化、销毁等工作交给spring容器来做。
IOC概念:程序中开发者不需要人工的创建对象,而是把创建的对象权利或者工作转交给Spring容器(IOC容器),让Spring容器去创建并管理这些对象,以达到程序的高度解耦的目的!
2.DI-依赖注入
Dependency Injection,说的是创建对象实例时,同时为这个对象注入它所依赖的属性。相当于把每个bean与bean之间的关系交给容器管理。而这个容器就是spring.
例如我们通常在Service层注入它所依赖的Dao 层的实例:在Controller 层注入Service层的实例。
DI给对象属性赋值的过程叫做依赖注入!
Spring 配置文件
首先新建项目的pom.xml文件中加入Spring的依赖。
<dependencies>
<!--加载依赖Spring-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.14</version>
</dependency>
</dependencies>
然后在项目的resource文件夹里新建applicationContext.xml文件。
注意:顶部黄色框框消除步骤:
1.bean标签和属性
bean标签
bean标签,是根标签beans内部必须包含的标签,它是用于声明具体的类的对象!
bean标签对应属性
Property | 属性解释 |
---|---|
class | 指点bean对应类的全路径 |
name | name是bean对应对象的一个标识 |
scope | 执行bean对象创建模式和生命周期 |
id | id是bean对象的唯一标识,不能添加特别字符 |
lazy-init | 是否延时加载,默认值false |
init-method | 对象初始化方法 |
destory | 对象销毁方法 |
2.bean标签的使用
2.1 name
name属性不能重复,但是可以指定多个,用逗号隔开!可以使用特殊字符,也可以根据name属性获取一个对象
2.2 scope
scope=“singleton” 单例模式,默认值,如果new了多个同一个对象时new出来的对象是一样的。
scope=“prototype” 多例模式,new了多个同一个对象时new出来的的对象是不一样的。
scope=“request” 表示在一次请求范围内,Spring容器中的对象保持一个,公用一个。
scope=“session” 表示在一次会话范围内,Spring容器中的对象保持一个,公用一个。
2.3 lazy-init
注意:只对单例有效
true懒加载:使用对象时才加载
false:spring一启动就加载
2.4 init-method和destroy-method
在实体类里创建初始化的方法和销毁的方法
在applicationContext.xml里引用
对象创建方法
1.无参构造方法创建对象
在applicationContext.xml里配置文件:
<!-- 方法1:用无参构造方法创建对象 -->
<bean id="p1" name="person1,person2" class="com.swjd.bean.Person" lazy-init="true" init-method="init" destroy-method="destroy">
<!-- 依赖注入(DI):把对象的属性赋给对象,赋值 -->
<property name="id" value="1"></property>
<property name="name" value="张三"></property>
<property name="sex" value="男"></property>
</bean>
在测试类里写:
// 1.启动并加载spring框架
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("applicationContext.xml");
// 2.拿person对象
Person person = context.getBean("p1",Person.class);
System.out.println(person);
2.带参构造方法创建对象
在applicationContext.xml里配置文件:
<!-- 方法2:用带参构造方法创建对象 -->
<bean id="p2" class="com.swjd.bean.Person">
<constructor-arg index="0" type="int" value="2"></constructor-arg>
<constructor-arg index="1" type="java.lang.String" value="李四"></constructor-arg>
<constructor-arg index="2" type="java.lang.String" value="男"></constructor-arg>
</bean>
在测试类里写:
// 1.启动并加载spring框架
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("applicationContext.xml");
// 2.拿person对象
Person person = context.getBean("p2",Person.class);
System.out.println(person);
3.静态工厂创建对象
首先新建一个beanfactory包定义一个PersonFactory.java类。
然后在PersonFactory.java类里创建静态方法:
// 创建person的静态方法
public static Person createPerson(){
System.out.println("静态");
return new Person(3,"王五","男");
}
在applicationContext.xml里调用静态工厂的方法:
<!-- 方法3:用静态工厂创建对象(不常用) -->
<bean id="p3" class="com.swjd.beanfactory.PersonFactory" factory-method="createPerson"></bean>
在测试类里写:
// 1.启动并加载spring框架
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("applicationContext.xml");
// 2.拿person对象
Person person = context.getBean("p3",Person.class);
System.out.println(person);
4.非静态工厂创建对象
首先新建一个beanfactory包定义一个NoPersonFactory.java类。
然后在NoPersonFactory.java类里创建非静态方法:
// 创建person的非静态方法
public Person createPerson(){
System.out.println("非静态");
return new Person(3,"王五","男");
}
在applicationContext.xml里调用非静态工厂的方法:
<!-- 方法4:用非静态工厂创建对象(不常用) -->
<bean id="noStaticfactory" class="com.swjd.beanfactory.NoPersonFactory"></bean>
<bean id="p4" factory-bean="noStaticfactory" factory-method="createPerson"></bean>
在测试类里写:
// 1.启动并加载spring框架
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("applicationContext.xml");
// 2.拿person对象
Person person = context.getBean("p4",Person.class);
System.out.println(person);
依赖注入
在新建的项目里配置好文件后,创建三个实体类,并创建好属性和方法。
1.set方法注入
在applicationContext.xml配置文件:
<!-- 1.调用set方法注入 -->
<bean id="man1" class="com.swjd.bean.Man">
<property name="id" value="1"></property>
<property name="name" value="季夏"></property>
<property name="age" value="20"></property>
</bean>
在测试类里写:
// 启动spring容器
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("applicationContext.xml");
System.out.println(context.getBean("man1", Man.class));
2.带参构造方法注入
在applicationContext.xml配置文件:
<!-- 2.调用带参构造方法注入 -->
<bean id="man2" class="com.swjd.bean.Man">
<constructor-arg index="0" type="int" value="2"></constructor-arg>
<constructor-arg index="1" type="java.lang.String" value="何新"></constructor-arg>
<constructor-arg index="2" type="int" value="20"></constructor-arg>
<constructor-arg index="3" type="com.swjd.bean.Dog" ref="dog1"></constructor-arg>
</bean>
在测试类里写:
// 启动spring容器
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("applicationContext.xml");
System.out.println(context.getBean("man2", Man.class));
3.P命名空间注入
在applicationContext.xml配置文件:
<!-- 3.P命名空间注入 -->
<bean id="man3" class="com.swjd.bean.Man" p:id="3" p:name="习上" p:age="20" p:dog-ref="dog1"></bean>
在测试类里写:
// 启动spring容器
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("applicationContext.xml");
System.out.println(context.getBean("man3", Man.class));
4.spel表达式注入
在applicationContext.xml配置文件:
<!-- 4.spel表达式注入 -->
<bean id="man4" class="com.swjd.bean.Man">
<!--man1指第一个创建的对象-->
<property name="id" value="#{man1.id}"></property>
<property name="name" value="#{man1.name}"></property>
<property name="age" value="#{man1.age}"></property>
</bean>
在测试类里写:
// 启动spring容器
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("applicationContext.xml");
System.out.println(context.getBean("man4", Man.class));
5.复杂类型注入
5.1 注入对象
在applicationContext.xml配置文件:
<!--配置另一个对象-->
<bean id="dog1" class="com.swjd.bean.Dog">
<property name="id" value="1"></property>
<property name="name" value="小白"></property>
<property name="sex" value="母"></property>
</bean>
<bean id="man1" class="com.swjd.bean.Man">
<property name="id" value="1"></property>
<property name="name" value="季夏"></property>
<property name="age" value="20"></property>
<!--加入对象的第一种方法(推荐使用)-->
<property name="dog" ref="dog1"></property>
<!--加入对象的第二种方法-->
<!-- <property name="dog">-->
<!-- <ref bean="dog1"></ref>-->
<!-- </property>-->
</bean>
在测试类里写:
// 启动spring容器
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("applicationContext.xml");
System.out.println(context.getBean("man1", Man.class));
5.2 注入数组
在applicationContext.xml配置文件:
<bean id="stu" class="com.swjd.bean.Student">
<property name="name" value="昂五"></property>
<!--注入数组-->
<property name="hobbies">
<array>
<value>足球</value>
<value>篮球</value>
<value>乒乓球</value>
<value>羽毛球</value>
</array>
</property>
</bean>
在测试类里写:
// 启动spring容器
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("applicationContext-stu.xml");
System.out.println(context.getBean("stu", Student.class));
5.3 注入集合
在applicationContext.xml配置文件:
<bean id="stu" class="com.swjd.bean.Student">
<property name="name" value="昂五"></property>
<!-- 注入集合 -->
<property name="subject">
<list>
<value>MyBatis<alue>
<value>Spring<alue>
</list>
</property>
</bean>
在测试类里写:
// 启动spring容器
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("applicationContext-stu.xml");
System.out.println(context.getBean("stu", Student.class));
5.4 注入map
在applicationContext.xml配置文件:
<bean id="stu" class="com.swjd.bean.Student">
<property name="name" value="昂五"></property>
<!-- 注入数组 -->
<property name="map">
<map>
<entry key="CN">
<value>中国</value>
</entry>
<entry key="RU">
<value>俄罗斯</value>
</entry>
</map>
</property>
</bean>
在测试类里写:
// 启动spring容器
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("applicationContext-stu.xml");
System.out.println(context.getBean("stu", Student.class));