spring框架
一、概念:
- spring是一个分层的JavaSE/EE full-stack(一站式)轻量级开源框架。是一个开源框架,是为了解决企业应用开发复杂性创建的。框架优势之一就是分层架构分层架构允许您选择使用哪一个组件,同时为 J2EE 应用程序开发提供集成的框架。
- 两个核心模块:
- 控制反转:IOC,也可叫做依赖注入DI
- 面向切面:AOP
- 七个模块:
二、详细配置
1. spring.xml文件配置bean
<!-- 配置bean -->
<!-- UserDaoOracleImpl userDaoOracleImpl = new UserDaoOracleImpl(); -->
<bean class="com.zhiyou.dao.impl.UserDaoMysqlImpl" id="userDaoMysqlImpl" name="userDaoMysqlImpl" scope="prototype" />
<!-- serviceImpl的实例化 -->
<bean class="com.zhiyou.serviceimpl.UserServiceImpl" id="us" name="us">
<!-- 在serviceimpl中还有一个ud属性等待赋值 -->
<property name="ud" ref="userDaoMysqlImpl"/>
</bean>
scope属性指定对象实例的模式:单例或者原型(prototype)
- 单例模式:spring.xml运行一次只创建一个对象:生命周期在spring使用destroy-method后销毁
- 原型:每次创建一个对象: 生命周期:每次调用生成一个,销毁通过垃圾回收器
2. 使用:
+ 加载spring.xml文件
`ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("spring.xml");`
+ 通过名字和"类型.class"来调用
`UserService us=context.getBean("us",UserServiceImpl.class);`
三、IOC(DI)属性注入
1. 什么是DI(IOC)?
当一个对象a调用另一个对象b的时候,传统的写法是在对象a中把对象b实例化,但是在spring中,a和b对象都是spring初始化并管理的,通过set方法注入或者constructor构造方法注入给b对象的引用。
简单理解:功能对象不是自己实例化,通过注入实现
2. set类型注入:需要添加set方法
< property>***< /property>
简单属性(简单属性包括八种基本数据类型+String):value
复杂属性:
+ 已实例化对象:<ref=“对象名字”/>
+ 未实例化对象:
+ 集合
javascript?linenums <property name="list"> <list> <bean class="com.zhiyou.dao.impl.UserDaoMysqlImpl"></bean> <ref bean="userDaoOracleImpl"/> <value>1</value> </list> </property>
- 图解:
3.构造方法注入:
<!-- 实例化service实现,使用构造方法完成属性的注入 -->
<bean class="com.zhiyou100.service.impl.UserServiceImpl" id="us" name="us">
<constructor-arg name="ud" ref="userDaoOracleImpl"/>
<constructor-arg name="num" value="100"/>
</bean>
- 图解:
四、生命周期
- 在ClassPathXmlApplicationContext被初始化之后,被配置的bean对象也被初始化,然后放到map集合中
- ClassPathXmlApplicationContext被销毁后,对应的map集合中的对象也会被销毁。注意,此时只针对单例模式的对象有效
- 如果scope设置成prototype,对象不是由ClassPathXmlApplicationContext来管理,生命周期也不会被管理
五、自动注入AutoWire
- 分类
-
byName(推荐):
在bean对应的对象map集合中,寻找是否有与变量同名的对象,如果有,直接拿来赋值 -
byType
在bean对应的对象map集合中,寻找是否有能给对象赋值的类型对象,如果有,直接拿来赋值
六、注解:
-
将自动注入功能使用注解annotation实现
<context:component-scan base-package="需要自动注入的包名"/
-
功能类头部加上注解
实例化类:@
1. 使用位置
1、属性中 限定属性的类型和作用等
2、方法上 对方法进行限定
3、用在类上 对类进行限定,声明类的作用
使用时间:
1、源代码
2、编译期
3、运行时
2. 常用类注解
@Repository 用在dao
@Service 服务
@Controller 控制,不能使用Component替换
@Component 如果该类别不好划分范围,但是需要交给水平管理。可以替换Repository和Service
这几个注解使用在功能类的头部
3. 常用属性注解:
@AutoWired 自动注入,直接加载属性头部
4. 单例、原型注解
七、AOP
- 什么是aop?
面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。
在不影响原来功能代码的基础上,使用动态代理加入自己需要的一些功能(比如权限的验证,事务的控制,日志的记录等等),移除之后,并不影响原来的功能
面向切面编程是通过动态代理实现的,是对面向对象思想的补充。 - aop通知的位置
1)before:在执行切入的方法之前,执行代码
2)after returning:在执行切入的方法正常执行(没有异常)之后,执行代码
3)after throwing:在执行切入的方法发生异常的时候,执行代码
4)after:在执行切入的方法无论是否发生异常,都必须最后执行代码
5)around:相当于before和after returning的组合 - 实现方式:
- 通过spring.xml配置形式
spring.xml
<bean class="com.zhiyou.aop.MyAop" id="myAop"></bean>
<aop:config proxy-target-class="true">
<aop:pointcut expression="execution(public * com.zhiyou.service.impl.UserServiceImpl.select(..))" id="pointcut1"/>
<aop:pointcut expression="execution(public * com.zhiyou.service.impl.UserServiceImpl.delete(..))" id="pointcut2"/>
<aop:aspect ref="myAop">
<aop:before method="before" pointcut-ref="pointcut1"/>
<aop:after method="after" pointcut-ref="pointcut1"/>
<aop:after-returning method="afterReturn" pointcut-ref="pointcut1"/>
<aop:after-throwing method="afterThrow" pointcut-ref="pointcut1"/>
<aop:around method="around" pointcut-ref="pointcut2"/>
</aop:aspect>
</aop:config>
public class MyAop {
public void before(){
System.out.println("打开事务");
}
public void after(){
System.out.println("关闭事务");
}
public void afterReturn(){
System.out.println("已经返回返回值");
}
public void afterThrow(){
System.out.println("出现异常,写入日志");
}
public Object around(ProceedingJoinPoint pjp){
System.out.println("切点之前执行");
Object o=null;
try {
o=pjp.proceed();
} catch (Throwable e) {
e.printStackTrace();
}
System.out.println("切点之后执行");
return o;
}
}
- 通过注解形式
<!--spring.xml--> <aop:aspectj-autoproxy proxy-target-class="true"/>
package com.zhiyou.aop;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
@Component
@Aspect
public class MyAop {
@Before("pointcut1()")
public void before(){
System.out.println("打开事务");
}
@After("pointcut1()")
public void after(){
System.out.println("关闭事务");
}
@AfterReturning("pointcut1()")
public void afterReturn(){
System.out.println("已经返回返回值");
}
@AfterThrowing("pointcut1()")
public void afterThrow(){
System.out.println("出现异常,写入日志");
}
@Around("pointcut1()")
public Object around(ProceedingJoinPoint pjp){
Object o=null;
System.out.println("切点之前执行");
try {
o=pjp.proceed();
} catch (Throwable e) {
e.printStackTrace();
}
System.out.println("切点之后执行");
return o;
}
@Pointcut("execution(public * com.zhiyou.service.impl.UserServiceImpl.delete(..))")
public void pointcut1(){
}
}