目录
一、概述
为什么要使用Spring框架?
- 松耦合:通过 xml 配置或注解即可完成 bean 的依赖注入
左:表演者和小提琴高耦合
右:通过依赖注入的方式,松耦合。表演者无需知道要演奏什么乐器,通过依赖注入的方式,不同的
环场合可以演奏不同的乐器。
- 方便测试
- 非侵入式
- 支持事务,AOP
什么时候需要使用Spring框架?
当 某些类的成员属性不需要变化时,可以用Spring框架管理。
User,Customer这种类不放到Spring中。
二、Maven+Spring环境搭建
- 创建Maven项目
-
(修改 pom.xml , jetty 插件配置 )
<build> <finalName>test</finalName> <plugins> <plugin> <groupId>org.mortbay.jetty</groupId> <artifactId>maven-jetty-plugin</artifactId> <version>6.1.25</version> <configuration> <scanIntervalSeconds>10</scanIntervalSeconds> <contextPath>/test</contextPath> <connectors> <connector implementation="org.mortbay.jetty.nio.SelectChannelConnector"> <port>9090</port> </connector> </connectors> </configuration> </plugin> </plugins> </build>
-
坐标依赖中Spring框架核心坐标
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.3.9.RELEASE</version> </dependency>
- 在src/main/resources中创建spring xml文件
三、控制翻转IOC
引入:
Inversion of Control。通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体将其所依赖的对象的引用传递给它。也可以说,依赖被注入到对象中。
IOC是这样一种思想:
大多数应用程序都是由两个或是更多的类通过彼此的合作来实现业务逻辑,这使得每个对象都需要获取与其合作的对象(也就是它所依赖的对象)的引用。如果这个获取过程要靠自身实现(自己new),那么这将导致代码高度耦合并且难以维护和调试。
例如Class A中用到了Class B的对象b,一般情况下,需要在A的代码中显式的new一个B的对象。
采用依赖注入技术之后,A的代码只需要定义一个私有的B对象,不需要直接new来获得这个对象,而是通过相关的容器控制程序来将B对象在外部new出来并注入到A类里的引用中。而具体获取的方法、对象被获取时的状态由配置文件(如XML)来指定。
IOC实例化bean的三种方式:
1、空构造模式
applicationContext.xml:
<bean id="hello" name="hello" class="com.mage.demo.Hello"></bean>
Test:
ApplicationContext act=new ClassPathXmlApplicationContext("applicationContex.xml");
Hello hello=(Hello)act.getBean("hello");
2、静态工厂模式
3、实例工厂模式
四、依赖注入DI
Dependency Injection。依赖注入可以看做是IOC的实际应用。理解DI的关键是:“谁依赖谁,为什么需要依赖,谁注入谁,注入了什么”
“谁依赖谁”:应用程序依赖于IoC容器
“为什么需要依赖“:应用程序需要IoC容器来提供对象需要的外部资源
“谁注入谁“:IoC容器注入应用程序某个对象,应用程序依赖的对象
“注入了什么”:就是注入某个bean所需要的属性值。如何给bean注入属性:
1、注入方式:
1、Set注入:
UserDao.java:
public class UserDao {
public String userLogin() {
return "我是UserDao中的userLogin()的方法";
}
}
UserService.java:
public class UserService {
private UserDao userDao;
public void userlogin() {
String res=userDao.userLogin();
System.out.println(res);
}
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
}
UserService中的成员userDao将会被自动赋值注入属性。
applicationContex.xml:
<!-- setter注入 -->
<bean id="userService" class="com.xxx.demo.UserService">
<!--ref是对于外部bean对象引用,与被引用的bean对象的id保持一致-->
<property name="userDao" ref="userDao"></property>
</bean>
Test:
public class App {
public static void main(String[] args) {
ApplicationContext applicationContext=
new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService=applicationContext.getBean("userService", UserService.class);
userService.userlogin();
}
}
UserService中的成员userDao将会被自动赋值注入属性,可以调用到userDao中的方法。
注:UserService必须要提供Setter方法。
2、构造器注入:
3、静态工厂注入:
4、实例化注工厂注入:
5、注解方式注入:
applicationContext.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"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config/>
<bean id="userDao" class="com.mage.demo.UserDao"></bean>
<bean id="userService" class="com.mage.demo.UserService"></bean>
/beans>
注解中只实现了IOC,并没有实现DI
UserService.java:
public class UserService {
@Aotuwired
private UserDao userDao;
public void userlogin() {
String res=userDao.userLogin();
System.out.println(res);
}
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
}
相当于@Autowired / @Resource代替了property了
6、自动扫描管理bean
如果项目中的bean太多,需要手动写多个bean,不方便。
applicationContex.xml只需配置:
<context:component-scan base-package="com.xxx"/>
2、Bean的作用域:
- singleton:spring的默认作用域,单例模式。对于每一个bean,整个项目只会存放一份,并且在加载时就创建。
lazy-int懒加载模式:=true时调用到某个bean时才会创建。 - prototype:请求一次创建一个,次次不同。调用时才创建,不是单例。
- Web类型的bean:request作用域、session 作用域、globalSession作用域
3、bean 的生命周期:
定义、初始化、使用和销毁4个阶段。
- 定义:在Spring中,通常是通过配置文档的方式来定义Bean的,在一个配置文档中,可以定义多个Bean。
- 初始化:
【singleton】:spring框架启动时初始化bean,并将初始化的bean放入缓存池中。
【lazy-init】 :使用时初始化。
【prototype】:每次调用时初始化。
web类型的bean: request每次请求 发生时初始化;session/globalSession每次会话开始时初始化。 - 使用:bean被使用时
- 销毁:
【singleton】:框架停止使用时被销毁。
【lazy-init】 :框架停止是被销毁。
【prototype】:每次使用结结束
web类型的bean:request请求结束时; session/globalSession每次会话结束时。
四、AOP
1、引入
OOP面向对象编程,关注的是某一个类。
2、环境搭建
- jar包依赖:pom.xml:
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.9</version>
</dependency>
- 添加命名空间和约束范围:
xmlns:aop="http://www.springframework.org/schema/aop"
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
- 配置AOP代理 :
<aop:aspectj-autoproxy/>
3、编写:
LogCut.java:
/**
* 声明切面组件
*/
@Component
@Aspect
public class LogCut {
/**
*定义切入点 匹配方法规则定义
*执行任意公共方法:execution(public *(..))
*执行任意的 set 方法:execution(* set*(..))
*执行 com.xxx.service包下任意类的任意方法:execution(* com.xxx.service.*.*(..))
*执行 com.xxx.service包 以及子包下任意类的任意方法:execution(* com.xxx.service..*.*(..))
*/
@Pointcut("execution (* com.xxx.service..*.*(..))") public void cut(){}
@Before(value="cut()")
public void before(){
System.out.println("前置通知.....");
}
@After(value="cut()")
public void after(){
System.out.println("最终通知....");
}
@AfterReturning(value="cut()")
public void afterReturning(){
System.out.println("返回通知....");
}
@AfterThrowing(value="cut()",throwing="e")
public void afterThrowing(Exception e){
System.out.println("异常通知....方法执行异常时执行:"+e);
}
4、AOP基于xml实现
applicationContext.xml:
<!-- aop 相关配置 -->
<aop:config>
<!-- aop 切面配置 -->
<aop:aspect ref="logCut">
<!-- 定义 aop 切入点 -->
<aop:pointcut expression="execution (* com.mage.service..*.*(..))" id="cut"/>
<!-- 配置前置通知 指定前置通知方法名 并引用切入点定义 -->
<aop:before method="before" pointcut-ref="cut"/>
<!-- 配置返回通知 指定返回通知方法名 并引用切入点定义 -->
<aop:after-returning method="afterReturning" pointcut-ref="cut"/>
<!-- 配置异常通知 指定异常通知方法名 并引用切入点定义 -->
<aop:after-throwing method="afterThrowing" throwing="e" pointcutW ref="cut"/>
<!-- 配置最终通知 指定最终通知方法名 并引用切入点定义 -->
<aop:after method="after" pointcut-ref="cut"/>
<!-- 配置环绕通知 指定环绕通知方法名 并引用切入点定义 -->
<aop:around method="around" pointcut-ref="cut"/>
</aop:aspect>
</aop:config>
5、代理模式
——有待深入理解
五、Spring整合JDBC
1、环境搭建
- pom.xml中添加:
<!-- mysql 驱动包 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.39</version>
</dependency>
<!-- c3p0 连接池 -->
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
<!-- spring jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
- 配置db.properties:
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/数据库名?useUnicode=true&characterEncod
ing=utf8
jdbc.user=root
jdbc.password=root
- 加载配置文件,applicationContex.xml:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task.xsd">
<!-- 加载 properties 配置文件 -->
<context:property-placeholder location="db.properties" />
<!-- 加载 数据库 配置文件 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driver}"></property>
<property name="jdbcUrl" value="${jdbc.url}"></property>
<property name="user" value="${jdbc.user}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!--配置jdbc数据的操作模板 -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
</beans>
- 查询所有用户
- 查询单条记录
- 多条件查询
- 不带主键插入操作
- 带主键插入操作
- 单条更新
- 批量更新
- 单条删除
- 批量删除
——详细代码见文档
五、Spring 事务
1、注解管理方式
- 环境搭建
在pom.xml中添加:
<!-- springs事务 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
applicationContext中添加添加命名空间:
xmlns:tx="http://www.springframework.org/schema/tx"
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
在applicationContext中:
<!-- 事务管理器定义 -->
<bean id="txManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
applicationContext配置注解支持:
<tx:annotation-driven transaction-manager="txManager"/
编写代码加上 注解@Transactional