目录
一、Spring框架
1、什么是Spring?
Spring是一个开源的、轻量级的项目管理框架。致力于JavaEE轻量级解决方案。不同于Struts2、mybatis,Spring不是替换原来的某个框架,而是对其进行整合管理。
Spring用来管理【创建|使用|销毁】项目中的组件,由于Spring可以生成项目中组件(项目中的service、dao、action,通常不管理实体类对象创建),也称Spring是一个工厂|容器。
2、Spring的优点
- 方便解耦,简化开发 (高内聚低耦合)
Spring就是一个大工厂(容器),可以将所有对象创建和依赖关系维护,交给Spring管理,spring工厂是用于生成bean
- AOP编程的支持
Spring提供面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等功能
- 声明式事务的支持
只需要通过配置就可以完成对事务的管理,而无需手动编程
- 方便程序的测试
Spring对Junit4支持,可以通过注解方便的测试Spring程序
- 方便集成各种优秀框架
Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如:Struts、Hibernate、MyBatis、 Quartz等)的直接支持
- 降低JavaEE API的使用难度
Spring 对JavaEE开发中非常难用的一些API(JDBC、JavaMail、远程调用等),都提供了封装,使这些API应用难度大大降低
3、Spring的体系结构
二、Spring框架搭建
1、引入Spring的依赖
- maven项目导入的依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
2、创建组件对象
public interface UserDao{
public void delete(String id);
public void save();
}
public class UserDaoImpl implement UserDao{
public void delete(String id){
System.out.println("删除成功"+id);
}
public void save(){
System.out.println("保存一个。。。。。");
}
}
3、引入Spring的配置文件
名称:任意名称,常用applicationContext.xml
位置:项目中跟下任意位置
4、通过工厂管理
<?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">
<!-- 管理dao对象
<bean> 配置需要创建的对象
id :用于之后从spring容器获得实例时使用的
class :需要创建实例的全限定类名
-->
<bean id="userDao" class="com.lin.UserDaoImpl"/>
</beans>
5、通过启动工厂测试
@Test
public void demo02(){
//从spring容器获得
//1 获得容器
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(“spring.xml”);
//2获得内容 --不需要自己new,都是从spring容器获得
UserDao userDao= (UserDao) applicationContext.getBean("userDao");
userDao.save();
}
三、Spring中的核心思想
1、IOC【控制反转】| DI【依赖注入】
- IOC控制反转 | DI依赖注入
将对象的创建由原来的(new)的方式转移到配置文件中,交由spring工程来创建对象,spring不仅要创建对象,还要建立类与类之间的关系,因此在控制反转的基础上又提出了依赖注入的概念。
2、AOP【面向切面编程】
3、set注入
- 八种基本类型、日期类型、数组类型注入
<!--基本类型+日期类型-->
<property name="id" value="1"/>
<property name="name" value="张三"/>
<property name="price" value="1.5"/>
<property name="sex" value="false"/>
<property name="birthday" value="2015/12/12 12:12:12"/>
<!--数组类型-->
<property name="strs">
<array>
<value>xiaoliu</value>
<value>xiaoli</value>
<value>xiaohao</value>
</array>
</property>
- 引用类型,集合类型注入
<!--引用类型注入-->
<property name="userDao" ref="userDao"/>
<!--集合类型-->
<property name="list">
<list>
<value>xiaozhang</value>
<value>xiaohao</value>
</list>
</property>
<property name="setData">
<set>
<value>停封</value>
<value>薄纸</value>
<value>关系</value>
</set>
</property>
<property name="maps">
<map>
<entry key="123" value="xiaosan"></entry>
<entry key="456" value="xiaosi"></entry>
</map>
</property>
<!--properties-->
<property name="props">
<props>
<prop key="driver">oracle.jdbc.OracleDriver</prop>
<prop key="url">jdbc:oracle:thin@localhost:1521:xe</prop>
</props>
</property>
注意:引用类型使用ref属性注入,基本类型使用value属性注入
4、构造注入
<bean id="userDao" class="com.lin.UserDaoImpl">
<constructor-arg name="id" value="123"/>
<constructor-arg name="name" value="123"/>
<constructor-arg name="price" value="123"/>
<constructor-arg name="strs" >
<array>
<value>zhangsan</value>
<value>lisi</value>
</array>
</constructor-arg>
</bean>
5、自动注入
- autowire=“byname”
根据注入的属性名与配置文件 中bean的id匹配,一致则注入,不一致报错
- autowire="byType"
根据注入的属性类型与配置文件中的类型匹配,类型一致注入(在多个实现类时,会产生歧义)
注意:无论使用以上哪种方式注入都需要为属性提供set方法
6、依赖注入装配Bean 基于注解
(1)注解:就是一个类,使用@注解名称
(2)开发中:使用注解取代 xml配置文件
1》 @Component 取代 <bean class=" ">
@Component("id") 取代 <bean id=" " class=" ">
2》web开发,提供3个@Component注解衍生注解(功能一样)取代
@Repository:dao层
@Service:service层
@Controller:web层
3》 依赖注入,给私有字段设值,也可以给setter方法设值
● 普通值:@Value(“ ”)
● 引用值:
方式1:按照【类型】注入:@Autowired
方式2:按照【名称】注入1:@Autowired @Qualifier("名称")
方式3:按照【名称】注入2:@Resource("名称")
4:生命周期:初始化:@PostConstruct
销毁:@PreDestroy
5:作用域:@Scope(“prototype”) -----多例
注解使用前提,添加命名空间,让Spring扫描含有注解类<context:component-scan base-package="" />
<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:component-scan base-package="com.lin.dao"></context:component-scan>
</beans>
7、Spring中bean的创建模式
<bean id="xxx" class="xxx" scope="singleton | prototype" />
-- singleton:单例 (默认)全局唯一,一个工厂只创建一次 【service、dao】
-- prototype:非单例 全局不唯一,每当使用时,都要重新创建一个新对象 【Struts2的action】
8、bean的生产原理:反射+无参构造方法
Class<UserDao> forName = (Class<UserDao) Class.forName("com.lin.UserDaoImpl");
UserDao newInstance = forName.newInstance();
newInstance.save();
9、bean的生命周期
- 随着工厂启动,所有单例bean随之创建,非单例的bean,每次使用时创建
- 工厂关闭,所有bean随之销毁(注意:Spring对多例bean管理松散,不会负责多例bean的销毁)
10、spring工厂创建对象的好处
- 使用配置文件管理java类,在生产环境中更换类的是现实不需要重新部署,修改文件即可
- Spring默认使用单例的模式创建bean,减少内存的占用
- 通过依赖注入建立了类与类之间的关系(使java之间关系更为清晰,方便了维护与管理)
四、AOP--面向切面编程
1、静态代理
目标类:被代理类称之为目标类
开发代理的原则:和目标类功能一致且实现相同的接口
(1)开发静态代理类
public class UserServiceStaticProxy implements UserService{
private UserService userService;
public void setUserService(UserService userService){
this.userService = userService;
}
public void save(){
try {
System.out.println("开启事务");
userService.save();
System.out.println("提交事务");
} catch (Exception e) {
System.out.println("回滚事务");
e.printStackTrace();
}
}
}
(2)配置静态代理类
<!--管理静态代理类-->
<bean id="userServiceStaticProxy" class="com.lin.UserServiceStaticProxy">
<!--注入目标类-->
<property name="userService" ref="userService"/>
</bean>
<!--管理业务成组件类-->
<bean id="userService" class="com.lin.UserServiceImpl"></bean>
(3)通过调用静态代理类完成功能
ApplicationContext context = new ClassPathXmlApplicationContext("spring,xml");
UserService bean = context.getBean("userServiceStaticProxy");
bean.save();
问题:每一个业务层开发一个静态代理类,不仅没有减轻工作量,甚至让我们的工作量多了一倍不止??
2、动态代理
通过jdk提供的Proxy这个类,动态为现有的业务生成代理类
Proxy.newProxyInstance(loader, interfaces, h); //返回值就是动态代理对象
参数1:当前线程类加载器
参数2:生成代理类的接口类型
参数3:通过代理类对象调用方法时会优先进入参数三中的invoke方法
(1)AOP中的几个重要概念
- 通知(Advice):处理目标方法以外的操作都称之为通知
- 切入点(PointCut):要为哪些类中的哪些方法加入通知
- 切面(Aspect):通知+切入点
(2)AOP的编程步骤
1》导入AOP依赖jar
●aopalliance-1.0.jar
●aspectjrt-1.7.4.jar
●aspectjweaver-1.7.4.jar
2》引入AOP明明空间
<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">
3》开发通知类
前置通知 MethodBeforeAdvice
环绕通知 MethodInterceptor
后置通知 AfterReturningAdvice
异常通知 ThrowsAdvice
4》配置AOP切面
<bean id="myTimeAdvice" class="com.lin.service.MyTimeAdvice"></bean>
<aop:config>
<!--切入点-->
<aop:pointcut expression="execution(* com.lin.service.UserServiceImpl.save(..))" id="pc"/>
<!--通知+切入点-->
<aop:advisor advice-ref="myTimeAdvice" pointcut-ref="pc"/>
</aop:config>
(3)execution表达式