一、Spring框架优点
1、方便解耦,简化开发,Spring就是一个大工厂,可以将所有对象创建和依赖关系维护,交给Spring管理。IOC的作用。方便解耦,简化开发,Spring就是一个大工厂,可以将所有对象创建和依赖关系维护,交给Spring管理。IOC的作用。
2、AOP编程的支持,Spring提供面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等功能。(可扩展性)
3、声明式事务的支持,只需要通过配置就可以完成对事务的管理,而无需手动编程。
4、方便程序的测试,Spring对Junit4支持,可以通过注解方便的测试Spring程序。
5、方便集成各种优秀框架,Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如:Struts2、Hibernate、MyBatis、Quartz等)的直接支持。
6、降低JavaEE API的使用难度,Spring 对JavaEE开发中非常难用的一些API(JDBC、JavaMail、远程调用等),都提供了封装,使这些API应用难度大大降低。
二、SpringIOC
1、什么是IOC
IOC -- Inverse of Control,控制反转,将对象的创建权力反转给Spring框架!!
控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。
解决问题:使用IOC可以解决的程序耦合性高的问题!!Spring的工厂读取配置文件。
2、IOC的程序入门
创建Java工程,导入坐标依赖
XML
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.12</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
编写Spring核心的配置文件,在src/main/resources目录下创建applicationContext.xml的配置文件,名称是可以任意的,但是一般都会使用默认名称。
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">
<!--IOC管理bean-->
<bean id="userService" class="com.qcby.service.impl.UserServiceImpl" />
</beans>
把log4j.properties的配置文件拷贝到resources目录下,做为log4j的日志配置文件。
编写测试方法。
java
import com.qcby.service.UserService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Demo1{
@Test
public void run1(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService = (UserService) applicationContext.getBean("userService");
userService.hello();
}
}
3、IOC技术总结
**ApplicationContext接口:**工厂的接口,使用该接口可以获取到具体的Bean对象。该接口下有两个具体的实现类。 springCould 配置中心
**ClassPathXmlApplicationContext:**加载类路径下的Spring配置文件。
**FileSystemXmlApplicationContext:**加载本地磁盘下的Spring配置文件。
3*、单例模式(补充)
单例模式是oop(面向对象编程)语言的一种概念,顾名思义,就是一个类只能有一个实例对象。
分为:懒汉式单例和饿汉式单例
01、懒汉式单例
特点:当需要使用对象的时候才进行实例化。
由于可能有多个线程同时要使用对象,因此需要考虑线程安全问题,防止并发访问时生成多个实例。
通常需要加锁来解决并发冲突,是用时间换空间的方案。
java
class Singleton{
//设置私有构造方法
private Singleton(){}
//声明一个Singleton对象为obj
private static Singleton obj;
//加锁保证obj只能实例化一次,时间换空间
public static synchronized Singleton getInstance(){
if(obj == null){
obj=new Singleton();
}
return obj;
}
}
传统实现方式中,每次获取实例都要被synchronized关键字串行化,即使已经生成了对象实例。
而我们加锁的目的是为了防止生成多个实例,因此其实只需要对生成实例的代码加锁,生成实例后,可支持并发访问,提高性能。
02、饿汉式单例
饿汉单例的特点是:类加载时便实例化对象。
能够在第一时间实例化对象,供其他方法使用,是拿空间换时间的方案
java
Class Singleton{
//私有构造方法
private Singleton(){ };
//类加载时就实例化对象 加static
private static Singleton obj=new Singleton();
public static Singleton getInstance(){
return obj;
}
}
通过static关键字,在类加载时创建对象。
4、Spring框架的Bean管理的配置文件方式
id属性,Bean起个名字,在约束中采用ID的约束,唯一,取值要求:必须以字母开始,可以使用字母、数字、连字符、下划线、句话、冒号 id:不能出现特殊字符。
class属性,Bean对象的全路径。
scope属性,scope属性代表Bean的作用范围。
singleton单例(默认值),最常用的方式。
prototype多例
request应用在Web项目中,每次HTTP请求都会创建一个新的Bean
session应用在Web项目中,同一个HTTP Session 共享一个Bean
Bean对象的创建和销毁的两个属性配置
说明:Spring初始化bean或销毁bean时,有时需要作一些处理工作,因此spring可以在创建和拆卸bean的时候调用bean的两个生命周期方法
init-method,当bean被载入到容器的时候调用init-method属性指定的方法
destroy-method,当bean从容器中删除的时候调用destroy-method属性指定的方法
单例的对象销毁:跟着容器工厂关闭才销毁
多例的对象销毁:垃圾回收机制进行回收的
XML
<bean id="userMapper" class="com.qcby.mapper.UserMapperImpl" init-method="init" />
java
@Test
public void run2(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
UserMapperImpl userMapper = (UserMapperImpl)applicationContext.getBean("userMapper");
System.out.println("userMapper是:"+userMapper);
}
5、实例化Bean对象的三种方式实例化Bean对象的三种方式实例化Bean对象的三种方式实例化Bean对象的三种方式
默认是无参数的构造方法(默认方式,基本上使用)
XML
<bean id="us" class="com.qcbyjy.service.UserServiceImpl" />
静态工厂实例化方式
XML
<!--静态工厂创建-->
<bean id="us" class="com.qcby.demo.StaticFactory" factory-method="createUs" />
java
public class StaticFactory {
//静态工厂方式
public static UserServiceImpl createUs(){
System.out.println("通过静态工厂的方式创建UserServiceImpl对象");
return new UserServiceImpl();
}
}
java
@Test
public void staticfactorytest(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService = (UserService) applicationContext.getBean("us");
System.out.println(userService);
}
实例工厂实例化方式
XML
<!--动态工厂的创建-->
<bean id="dfactory" class="com.qcby.demo.Dfactory" />
<bean id="us2" factory-bean="dfactory" factory-method="createUs" />
java
public class Dfactory {
//动态工厂
public UserService createUs(){
System.out.println("实例化工厂的方式");
return new UserServiceImpl();
}
}
java
@Test
public void dfactorytest(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService1 = (UserService) applicationContext.getBean("us2");
System.out.println("userService1是:" + userService1);
}
三、DI依赖注入
1、依赖注入的概述
IOC和DI的概念
IOC:Inverse of Control,控制反转,将对象的创建权反转给Spring!!
DI:Dependency Injection,依赖注入,在Spring框架负责创建Bean对象时,动态的将依赖对象注入到Bean组件中!!
2、原始set方法注入值
首先实体类中有set方法
java
@Test
public void DITest(){
UserServiceImpl userService = new UserServiceImpl();
userService.setMsg("zjc");
userService.hello();
System.out.println(userService);
}
3、属性的set方法注入值
java
<bean id="userService" class="com.qcby.service.impl.UserServiceImpl">
<property name="msg" value="qwq"></property>
</bean>
java
@Test
public void DITest2(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
// UserServiceImpl userService = (UserServiceImpl) applicationContext.getBean("userService");
// userService.setMsg("测试");
UserService userService = (UserService) applicationContext.getBean("userService");
// userService.setMsg();
// userService.toString();
System.out.println(userService);
}
4、属性构造方法方式注入值
首先实体类中要有有参构造方法
XML
<bean id="userService2" class="com.qcby.service.impl.UserServiceImpl">
<!--<property name="msg" value="qwq"></property>-->
<!--<property name="userMapper" ref="userMapper"></property>-->
<constructor-arg name="msg" value="121"/>
<constructor-arg name="userMapper" ref="userMapper" />
</bean>
java
@Test
public void DITest3(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
// ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml","applicationContext1.xml");
UserService userService = (UserService) applicationContext.getBean("userService2");
userService.hello();
System.out.println(userService);
}
5、数组,集合(List,Set,Map),Properties等的注入
XML
<bean id="collectionBean" class="com.qcby.demo.CollectionBean">
<property name="strs">
<array>
<value>zjc</value>
<value>wxy</value>
</array>
</property>
<property name="list">
<list>
<value>熊大</value>
<value>熊二</value>
</list>
</property>
<property name="map">
<map>
<entry key="qq" value="ww"/>
<entry key="mm" value="nn"/>
</map>
</property>
<property name="properties">
<props>
<prop key="username">admin</prop>
<prop key="password">123456</prop>
</props>
</property>
</bean>
java
@Test
public void CollectionTest(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
CollectionBean collection = (CollectionBean) applicationContext.getBean("collectionBean");
System.out.println("collection:::"+collection);
}
四、多配置文件方式
1、直接在工厂创建的时候加载多个配置文件
java
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
"applicationContext.xml","applicationContext2.xml");
2、在主配置文件中通过<Import>标签引入所有的配置文件
这种情况只需要在工厂创建的时候加载一个主配置文件即可
XML
<import resource="applicationContext1.xml"/>
<import resource="applicationContext2.xml"/>