2020.06.25 今天是端午节,也是我的“开学”第一课,感触很多一直以来我知道自己学的不够,也还有很多要学,可是当这座山摆在我面前的时候,才知道之前的自己逃避了很多。 ------please try harder.
Spring 框架学习
Spring的诞生
Spring : 春天 泉水
官网: https://spring.io/ GO
Spring诞生以前 Java Web 的开发还是以Java EE 技术为主体,后来慢慢的Java EE 的臃肿和低效被很多人诟病,于是在2002年 Rod Johnson提出了 Inteface 21 的思想应该以技术和实用为准的主张,也是最早的Spring框架的雏形,2003year2month第一个开源的Spring诞生。
Spring诞生后别誉为 企业一站式开发 因为Spring涵盖了 表现层,业务层,持久层 而Spring框架并不是为了取代某个框架 而是以高度的开放性与其他框架进行无缝的整合。
Spring框架的组成
Spring框架大约由20个功能模块组成,这些模块被分为六大部分:Core Container ,DataAccess/Integration,Web,AOP,Instrumentation,Test。
优势,目标,原则
Spring框架是一个轻量级的框架有着强大和稳定的功能并且没有额外负担。
Spring的目标: 1.让现有技术更易使用 2.养成良好的编程习惯(最佳实践)
Spring的原则:不重复造轮子 如果有好的解决方案 Spring就不会再去重复性的实现,而是对其提供技术支持。
Spring jar下载
下载地址:https://repo.spring.io/webapp/#/artifacts/browse/tree/General/libs-release-local/org/springframework/spring/4.2.0.RELEASE download
版本:
RELEASE 发布版 (稳定)
BETA 测试版
结构:
readme.txt 注意事项
notice.txt 说明文件
license.txt 授权文件
docs 说明文档
libs jar包存放
Spring IOC
Spring IOC称为控制反转(Inversion of Control .Ioc),也称为依赖注入(Dependency Injection .DI)是面向对象的一种设计理念,用于降低程序代码之间的耦合度。
Spring是一个Bean容器可以帮助我们管理JavaBean(帮助我们构建实例对象)。
Spring IOC实现依赖的jar包:
普通类型注入
//Spring IOC实现步骤 及关键知识点
//使用Spring IOC实现对JavaBean 实例化一个JavaBean
//创建 spring配置文件 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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 定义Student并注入值 Student必须是一个标准的JavaBean 因为-->
<!-- Spring 注入底层还是调用JavaBean的setter方法 -->
<!-- 属性注入 -->
<bean id="stu" class="com.entity.Student">
<property name="name">张三</property>
<property name="age">30</property>
</bean>
<!-- p命名空间注入 头信息加上
xmlns:p="http://www.springframework.org/schema/p" -->
<bean id="stu2" class="com.entity.Student" p:name="王五" p:age=30 />
<!-- 构造注入 单参/多参 -->
<bean id="stu3" class="com.entity.Student">
<constructor-arg value="我叫张三" />
</bean>
<!-- index为参数下标 -->
<bean id="js" class="com.entity.Person">
<constructor-arg index="0" value="我叫:马斯克:"></constructor-arg>
<constructor-arg index="1" value=30 ></constructor-arg>
</bean>
</beans>
//此处作为测试 获取 Student
//读取配置文件 applicationContext.xml要在资源文件目录下
ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
//从spring容器获取Student实例 返回的是一个Object要进行强转
Student stu=(Student)context.getBean("stu"); //对应配置文件的id
System.out.print(stu);
Console:
Student[name=张三,age=30]
引用数据类型注入
以上列出类普通属性及复杂属性的注入方式,当类的属性是一个对象时就用到了引用数据类型的注入问题。
//举例:笔记本专卖店可以根据客户的需求 问电脑制造商 进货到不同品牌的电脑
//电脑制造商
public interface ComputerVeder(){
void computerInfo();
}
//制造商可以制造的电脑类型
public class ASUS implements ComputerVeder(){
void computerInfo(){
//制造了一台华硕电脑
}
}
public class DELL implements ComputerVeder(){
void computerInfo(){
//制造了一台戴尔电脑
}
}
//.....可以制造的其他类型的电脑
//专卖店
public class Computer(){
//电脑厂商
private ComputerVeder cv;
}
//applicationContext.xml
<!-- 制造的各种类型电脑 -->
<bean id="asusComputer" class="com.ASUS">
<bean id="dellComputer" class="com.DELL">
.....
<!-- 配置多个客户需求品牌电脑 -->
<!-- 进货了一台华硕电脑 -->
<bean id="asus" class="com.Computer">
<property name="cv" ref="asusComputer"/>
</bean>
<!-- 进货了一台戴尔电脑 -->
<bean id="dell" class="com.Computer">
<property name="cv" ref="dellComputer" />
</bean>
//客户去专卖店买电脑
ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
//根据客户需求 专卖店去进到不同的货 asus/dell
Computer com=(Computer )context.getBean("asus");
引用类型数据类型注入值方式如上 通过ref指向的方式注入值,通过配置文件可以看到Spring管理Bean的灵活性,对象之间的依赖关系存在配置文件中,而不是代码中 使用时通过唯一标识id访问获取到实例。
Ioc总结
在上述的实例和应用中就展示了 IOC 和DI的本质。
IOC(inverse of control) 控制反转
property name=“stuInterface” ref=“bean配置实例化对象得id”>
学习Spring IOC之前实现一个接口实现某个类的操作,是在类中指定的可以清楚看到指向的某个实现类 使用spring后将指向权交由外部配置文件管理 即控制权进行了反转(转移)。
DI (dependency injection)依赖注入
property name=“name”>张三
将以前手动 setter方式转为 spring的内部自动调用setter方法进行值或对象的赋值操作 即spring帮我们赋值,帮我们设置
自我理解 DI 和 IOC 相互依赖由DI注入值给类中的对象 再由IOC控制指向的某个具体的 bean,符合设计原则——迪米特原则,越少知道的原则,依赖于抽象不依赖域具体(依赖于接口不依赖实现)。
Spring AOP
AOP和OOP的关系:它俩之间互为互补,没有好坏之分,是两种不同的编程思想,AOP一般用于访问控制,事务管理,性能检测。
AOP的使用
AOP : aspect oriented programming 面向切面(方面)编程
OOP: object oriented programming 面向对象编程
依赖的jar:
<!-- 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"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
//实现Spring AOP 日志记录功能
<!-- 将定义好的日志记录工具类 放进spring容器 -->
<bean id="intercept" class="org.util.SysInterCept" />
<!--AOP切入配置-->
<aop:config>
<!-- 定义切入的方法 切入点 exprssion=”execution(指定切入的范围)“-->
<aop:pointcut id="point" expression="execution(* com.dao.*.*(..))">
<!-- 定义切入时机 和执行的方法 织入 -->
<aop:aspect ref="intercept">
<!-- 前置增强 method指定日志工具类定义的前置方法-->
<aop:before method="beforPoint" pointcut-ref="point" />
<!-- 后置增强 -->
<aop:after-returning method="afterRunning" pointcut-ref="point" returning="result">
<!-- 异常抛出增强 throwing指定注入异常实例 -->
<aop:after-throwing method="afterThrowing" pointcut-ref="point" throwing="e">
</aop:aspect>
</aop:cofig>
</beans>
概念及通知类型
AOP的基本概念:
切面(Aspect) : 可以理解为通知和切入点的组成。
连接点(Join Point): 定义执行织入的操作范围(方法)。
切入点(Point): 对连接点的具体描述指定 expression(…)。
增强处理(Advice): 也叫通知就是方法执行过程中的织入时机。
织入(Weaving): 对定义执行增强处理的具体实现的方法体如日志工具类的前置增强(beforPoint)。
目标对象(Target object): 被一个或多个切面增强的对象。
AOP代理对象(AOP proxy): 由AOP定义执行增强处理的对象。
AOP的五种通知类型
1.前置通知(开始) Before 方法执行前
2.后置通知(完成) After 方法执行后
3.异常通知(错误)After -throwing 出现异常执行
4.返回通知(最后) After-returning 无论如何都执行
5.环绕通知 Around 将前几通知进行的一个整合 包裹了被通知的方法
//日志记录工具类
import org.aopalliance.intercept.Joinpoint;
public class SysInterCept(){
//日志记录
private Logger logger=Logger.getLogger(SysInterCept.class);
//前置通知
public void beforePoint(JoinPoint point){
logger.info("调用" + jPoint.getTarget()+"的"+jPoint.getSignature().getName() + "方法,传入参数:"+jPoint.getArgs());
}
//后置增强 如果需要接收方法返回值要在配置文件中加上 returning=result(对应)
public void afterRunning(Object result) {
logger.info("方法执行结束返回结果"+result);
}
//异常抛出增强
public void afterThrowing(JoinPoint point,RuntimeException e){
logger.info("调用"+point.getSignature().getName()+"方法,出现异常"+e);
}
}
AOP总结
AOP总结:
1.它的本质是方法拦截
2.在方法执行之前,或方法执行之后,自动完成某些事
3.拦截到方法以后,要做什么事(增强,通知 advice -前置通知,后置通知)
4.定义切入点即那些方法会拦截(拦截的面有多大)
Spring使用进阶
在日常开发中通常使用 xml +注解的方式混合开发
注解式 IOC
Spring提供的快速配置一个Bean对象的注解:
@Component 组件 用于 JaveBean
@Repository 仓库 持久层 一般使用于 daoimpl
@Service 服务 业务层 一般用于 bizimpl serviceimpl
@Controller 控制器 表现层 一般用于 servlet
注解式配置Bean对象等同于xml中配置Bean的方式,可以在注解中指定Bean的id名 如@Service(“user”),如果没有指定则默认为 类名的首字母小写其余不变 的注解式Bean命名(id)规则。
用法: 在类的上方写入相对应的注解
四个注解作用都是用于在Spring容器快速配置一个Bean实例,至于在不同层使用不同的注解,能使组件的用途更加清晰可读性强。
Spring提供的注解式Bean的装配
@Autowired 注解 按照类型匹配的方式实现值注入
@Qualifier(“userDao”) 注解 注入类型匹配较多个时 使用此注解指定所需的Bean名称。
//注解式AOP
//使用注解式AOP要启动Spring的注解扫描容器
<!-- applicationContext.xml 使用aop的头声明信息 -->
<!-- 开启注解扫描 -->
<context:compont-scan base-package="com.service" />
//实现注解式注入
@Repository
public class UserDaoImpl implements UserDao(){
//重写的方法体....
}
@Service
public class UserServiceImpl implements UserService(){
//实现自动装配
@Autowired
@Qualifier("userDaoImpl")//当类型较少 可以不写
private UserDao uDao;
//方法体.....
}
java提供的@Resource注解也可以实现装配, @Resource可以根据属性名或setter方法进行注入 — 可以在属性名或对应的setter方法上指定注解实现注入。
注解式AOP
AspectJ框架
AspectJ是一个面向切面的框架,它扩展了AOP语法,能在编译器提供代码的织入,@AspectJ是AspectJ5的新增功能使用JDK 5.0注解技术和正规的AspectJ切点表达式来描述切面,所以在使用@AspectJ之前要保证JDK版本是5.0。或以上版本
同理使用注解是AOP也要在applicationContext.xml中启动注解支持。
<aop:aspectj-autoproxy />
注解式AOP的使用
注解式AOP使用步骤
@Component 放入Spring容器
@Aspect 定义为一个切面
在每个指定的方法上定义连接点指定切入的方法范围
wan