Spring5学习 (核心)
Spring5
官方文档:https://docs.spring.io/spring/docs/5.3.0-SNAPSHOT/spring-framework-reference/index.html
zip下载地址:https://repo.spring.io/release/org/springframework/spring/5.2.6.RELEASE/
bean注入:
无参构造 (set注入 多种方式https://docs.spring.io/spring/docs/5.3.0-SNAPSHOT/spring-framework-reference/core.html#beans-setter-injection)
classpath下beans.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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 使用Spring创建bean -->
<bean id="userDao" class="com.yan.dao.impl.UserDaoImpl">
</bean>
<bean id="userDaoOracle" class="com.yan.dao.impl.UserDaoImplOracle">
</bean>
<bean id="userService" class="com.yan.service.impl.UserServiceImpl">
<!--要有set方法-->
<property name="userDao" ref="userDaoOracle">
</property>
</bean>
</beans>
使用:
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
UserService userService = (UserService)context.getBean("userService");
userService.getUser();
有参构造 (构造器注入)
下标
<bean id="hello" class="com.yan.entity.Hello">
<constructor-arg index="0" value="str000">
</constructor-arg>
<constructor-arg index="1" value="1">
</constructor-arg>
</bean>
类型
<bean id="hello" class="com.yan.entity.Hello">
<constructor-arg type="java.lang.String" value="str000">
</constructor-arg>
<constructor-arg type="java.lang.Integer" value="1">
</constructor-arg>
</bean>
参数名
<!-- 参数名 -->
<bean id="hello" class="com.yan.entity.Hello">
<constructor-arg name="str" value="str000">
</constructor-arg>
<constructor-arg name="num" value="1">
</constructor-arg>
</bean>
bean引用
<bean id="str" class="java.lang.String">
<constructor-arg type="java.lang.String" value="str000">
</constructor-arg>
</bean>
<bean id="num" class="java.lang.Integer">
<constructor-arg type="int" value="1">
</constructor-arg>
</bean>
<bean id="hello" class="com.yan.entity.Hello">
<constructor-arg name="str" ref="str">
</constructor-arg>
<constructor-arg name="num" ref="num">
</constructor-arg>
</bean>
构造函数声明:
public Hello(String str,Integer num)
合并配置文件
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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<import resource="beans.xml"/>
<import resource="beans2.xml"/>
</beans>
bean作用域
配置方法:bean的scope属性
<bean id="hello" class="com.yan.entity.Hello" scope="prototype">
<constructor-arg name="str" ref="str">
</constructor-arg>
<constructor-arg name="num" ref="num">
</constructor-arg>
</bean>
可选值:
singleton 单例(默认)
prototype 多例
request
session
application
websocket
自动装配bean
xml (byName,byType)
byName:要求id全局唯一并且和要注入的属性的变量名一致
byType: 要求此类型实例全局唯一并且和要注入的属性类型一致
<bean id="dog" class="com.yan.entity.Dog">
</bean>
<bean id="cat" class="com.yan.entity.Cat">
</bean>
<bean id="people" class="com.yan.entity.People" autowire="byName">
</bean>
java代码
注解
额外配置:
导入context命名空间并且开启注解支持:
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config/>
</beans>
demo
xml配置:
<context:annotation-config/>
<bean id="dog" class="com.yan.entity.Dog">
</bean>
<bean id="cat" class="com.yan.entity.Cat">
</bean>
<bean id="people" class="com.yan.entity.People">
</bean>
代码中配置(有注入注解可以没用set方法):
public class People {
private String name;
@Autowired
private Dog dog;
@Autowired
private Cat cat;
public Dog getDog() {
return dog;
}
public Cat getCat() {
return cat;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
@Autowired默认是byType方式注入的,类型不唯一byName
@Resource 默认是byName方式注入的,名字不唯一byType,是java原生注解可以实现和@Autowired类似的功能
注解开发
配置文件
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<!-- 组件扫描 -->
<context:component-scan base-package="com.yan.annotation"/>
<!-- 开启注解支持-->
<context:annotation-config/>
</beans>
bean IOC:
模式注解:@Component,@Controller,@Service,@Repository,@Mapper,@SpringBootApplication...
属性注入:
@Autowried,@Value
全面使用注解(java config方式)
配置类
@Configuration
public class Config {
@Bean
public User user(){
return new User();
}
}
使用
public class MyTest {
public static void main(String[] args) {
ApplicationContext context=new AnnotationConfigApplicationContext(Config.class);
User user = (User) context.getBean("user");
}
}
@Configuration用于标注一个配置类,可以和@ComponentScans,@Import等注解完成诸如扫描包,合并配置文件等功能
AOP
静态代理
真实类:房东
public class Host implements Rent {
@Override
public void rent() {
System.out.println("我是房东,我要出租房子");
}
}
代理类:租房中介
public class Proxy implements Rent {
private Rent host;
@Override
public void rent() {
System.out.println("先发布租房信息");
host.rent();
System.out.println("出租完房子提供后续管理");
}
public void setHost(Rent host) {
this.host = host;
}
}
接口:出租
public interface Rent {
void rent();
}
客户类:房客
public class Client{
public static void main(String[] args) {
Host host=new Host();
Proxy proxy=new Proxy();
proxy.setHost(host);
proxy.rent();
}
}
缺点:每个代理方法的都要手动处理代理逻辑,每个接口都要有新的代理类,冗余代码多
动态代理
动态代理的代理类是动态生成的
基于接口
jdk动态代理
Proxy 获取代理对象
InvocationHandler 调用处理程序
接口:
public interface Rent {
void rent();
}
真实类:
public class Host implements Rent {
@Override
public void rent() {
System.out.println("我是房东,我要出租房子");
}
}
代理处理类
//这个类动态生成代理类,并用invoke方法调用原来方法,可以在其中添加代理逻辑
public class ProxyInvocationHandler implements InvocationHandler {
private Rent rent;
public void setHost(Rent rent) {
this.rent = rent;
}
//动态生成代理类
public Rent getProxy(){
Rent proxyInstance = (Rent) Proxy.newProxyInstance(this.getClass().getClassLoader(), rent.getClass().getInterfaces(), this);
return proxyInstance;
}
//处理代理实例并返回结果
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = method.invoke(rent, args);
return result;
}
}
客户类
public class Client {
public static void main(String[] args) {
ProxyInvocationHandler pih=new ProxyInvocationHandler();
pih.setHost(new Host());
Rent proxy = pih.getProxy();
proxy.rent();
}
}
通用代理工具类:
//通用代理类
//这个类动态生成代理类,并用invoke方法调用原来方法,可以在其中添加代理逻辑
public class CommonProxyInvocationHandler implements InvocationHandler {
private Object realObject;
public void setRealObject(Object realObject) {
this.realObject = realObject;
}
//动态生成代理类
public Object getProxy(){
Object proxyInstance = Proxy.newProxyInstance(this.getClass().getClassLoader(), realObject.getClass().getInterfaces(), this);
return proxyInstance;
}
//处理代理实例并返回结果
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("方法执行前");
Object result = method.invoke(realObject, args);
System.out.println("方法执行后");
return result;
}
}
匿名类实现
//用匿名类实现
Object realObject= new Host();
InvocationHandler invocationHandler = new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println(method.getName()+"执行前");
Object result = method.invoke(realObject, args);
System.out.println(method.getName()+"执行后");
return result;
}
};
Object proxyInstance = Proxy.newProxyInstance(Client.class.getClassLoader(), realObject.getClass().getInterfaces(), invocationHandler);
((Rent)proxyInstance).rent();
优点:一个动态代理类可以处理一类代理业务
基于类
cglib动态代理
基于 java字节码
javasist
AspectJ
使用Spring实现aop
Spring代理实际上是对JDK代理和CGLIB代理做了一层封装,并且引入了AOP概念:Aspect、advice、joinpoint等等,同时引入了AspectJ中的一些注解@pointCut,@after,@before等等.Spring Aop严格的来说都是动态代理,所以实际上Spring代理和Aspectj的关系并不大.(Aspectj有其自己的操作方法-->特殊编译方式在生成字节码阶段织入)
使用实现Spring原生Api+xml配置方式(Spring默认使用 JDK 动态代理)
增强代码
前置增强
public class BeforeExec implements MethodBeforeAdvice {
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
System.err.println(method.getName()+"执行前");
}
}
后置增强
public class AfterExec implements AfterReturningAdvice {
@Override
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
System.err.println(method.getName()+"执行后"+" 返回值是:"+returnValue);
}
}
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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="userService" class="com.yan.aop.service.impl.UserServiceImpl"/>
<bean id="beforeLog" class="com.yan.aop.log.BeforeExec"/>
<bean id="afterExec" class="com.yan.aop.log.AfterExec"/>
<!--配置aop-->
<aop:config>
<!--配置切入点-->
<aop:pointcut id="pointcut" expression="execution(* com.yan.aop.service.impl.*.*(..))"/>
<!-- 配置增强-->
<aop:advisor advice-ref="beforeLog" pointcut-ref="pointcut"/>
<aop:advisor advice-ref="afterExec" pointcut-ref="pointcut"/>
</aop:config>
</beans>
使用自定义切面类和切面配置切入
切面类
public class AspectLog {
public void before(){
System.out.println("方法执行前");
}
public void after(){
System.out.println("方法执行后");
}
}
配置文件:
<bean id="userService" class="com.yan.aop.service.impl.UserServiceImpl"/>
<bean id="aspect" class="com.yan.aop.log.AspectLog"/>
<aop:config>
<aop:aspect ref="aspect">
<aop:pointcut id="point" expression="execution(* com.yan.aop.service.impl.*.*(..))"/>
<aop:before method="before" pointcut-ref="point"/>
<aop:after method="after" pointcut-ref="point"/>
</aop:aspect>
</aop:config>
这种方法无法获取真实类的一些信息
注解切入
切面类
@Aspect
public class AnnotationLog {
//切入点的注解
@Pointcut(value="execution(* com.yan.aop.service.impl.*.*(..))")
private void pointcut(){}
@Before("execution(* com.yan.aop.service.impl.*.*(..))")
public void before(JoinPoint joinPoint){
// System.out.println(joinPoint.getSignature());
System.out.println("前置通知--->before");
}
@After("AnnotationLog.pointcut()")
public void after(JoinPoint joinPoint){
// System.out.println(joinPoint.getSignature());
System.out.println("后置通知--->after");
}
//最终通知
@AfterReturning(value="AnnotationLog.pointcut()", returning="result")
public void afterReturning(Object result){
System.out.println("后置通知");
}
@Around("AnnotationLog.pointcut()")
public void around(ProceedingJoinPoint joinPoint) throws Throwable {
//System.out.println("around "+joinPoint.getSignature());
System.out.println("环绕通知前--->around after");
Object proceed = joinPoint.proceed(joinPoint.getArgs());
System.out.println("环绕通知后--->around after");
}
//异常抛出通知
@AfterThrowing(value="AnnotationLog.pointcut()" , throwing="e")
public void find(Throwable e ){
System.out.println("异常抛出通知======"+e.getMessage());
}
}
配置:
<bean id="userService" class="com.yan.aop.service.impl.UserServiceImpl"/>
<bean id="annotationAspectLog" class="com.yan.aop.log.AnnotationLog"/>
<!-- true代表开启cglib注解 -->
<aop:aspectj-autoproxy proxy-target-class="true"/>
前后顺序
环绕通知前--->前置通知-->环绕通知后--->后置通知-->最终通知
Spring5学习 (核心)的更多相关文章
- iOS学习——核心动画
iOS学习——核心动画 1.什么是核心动画 Core Animation(核心动画)是一组功能强大.效果华丽的动画API,无论在iOS系统或者在你开发的App中,都有大量应用.核心动画所在的位置如下图 ...
- iOS学习——核心动画之Layer基础
iOS学习——核心动画之Layer基础 1.CALayer是什么? CALayer我们又称它叫做层.在每个UIView内部都有一个layer这样一个属性,UIView之所以能够显示,就是因为它里面有这 ...
- spark 入门学习 核心api
spark入门教程(3)--Spark 核心API开发 原创 2016年04月13日 20:52:28 标签: spark / 分布式 / 大数据 / 教程 / 应用 4999 本教程源于2016年3 ...
- spring5学习笔记
Spring5 框架概述 1.Spring 是轻量级的开源的 JavaEE 框架 2.Spring 可以解决企业应用开发的复杂性 3.Spring 有两个核心部分:IOC 和 Aop (1)IOC:控 ...
- ❀ Spring5学习大总结
一.了解 Spring 基本介绍.主要思想 IoC/DI 1.了解 Spring 基本介绍 (1) Spring是什么? Spring 是一个轻量级的 DI/IoC 和 AOP 容器的开源框架,致力于 ...
- Linux学习-核心的编译与安装
编译核心与核心模块 核心与核心模块需要先编译起来,而编译的过程其实非常简单,你可以先使用『 make help 』去查 阅一下所有可用编译参数, 就会知道有底下这些基本功能: [root@study ...
- Linux学习-核心编译的前处理与核心功能选择
硬件环境检视与核心功能要求 根据自己的需求来确定编译的选项 保持干净原始码: make mrproper 我们还得要处理一下核心原始码底下的残留文件才行!假设我们是第一次 编译, 但是我们不清楚到底下 ...
- Linux学习-核心与核心模块
谈完了整个开机的流程,您应该会知道,在整个开机的过程当中,是否能够成功的驱动我们主机的硬 件配备, 是核心 (kernel) 的工作!而核心一般都是压缩文件,因此在使用核心之前,就得要将他解 压缩后, ...
- Spring MVC学习------------核心类与接口
核心类与接口: 先来了解一下,几个重要的接口与类. 如今不知道他们是干什么的没关系,先混个脸熟,为以后认识他们打个基础. DispatcherServlet -- 前置控制器 HandlerMap ...
随机推荐
- 原生php 实现 thinkphp 数据库链式操作!!!
https://www.bilibili.com/video/BV1v4411A74Q?p=16&spm_id_from=pageDriver 没事可以看两遍,加深一下基础知识!!!
- OAuth2 Token 一定要放在请求头中吗?
Token 一定要放在请求头中吗? 答案肯定是否定的,本文将从源码的角度来分享一下 spring security oauth2 的解析过程,及其扩展点的应用场景. Token 解析过程说明 当我们使 ...
- Ambassador-09-prefix正则表达式
设置 prefix_regex: true,即prefix就可以设置成正则表达式 --- apiVersion: getambassador.io/v2 kind: Mapping metadata: ...
- Ambassador-05-自动重试
自动重试定义: retry_policy: retry_on: <string> num_retries: <integer> per_try_timeout: <str ...
- 【运维】Shell -- 快速上手Shell脚本
1.Shell概述 shell脚本是利用shell的功能所写的一个[程序(program)].这个程序是使用纯文本文件,将一些shell的语法与命令(含外部命令)写在里面,搭配正则表达式.管道命令与数 ...
- The Dole Queue UVA - 133
In a serious attempt to downsize (reduce) the dole queue, The New National Green Labour Rhinoceros ...
- Day13_71_线程同步(synchronized)
线程同步 * 异步编程模型和同步编程模拟的区别? - 有T1和T2 两个线程 > 异步编程模型:T1线程执行T1的,T2线程执行T2的,谁也不等谁 > 同步编程模型:T1和T2 线程执行, ...
- Jenkins 项目类型及配置项
0. 简介 1. Freestyle project 1)General 2)源码管理 3)构建触发器 4)构建环境 5)构建 6)构建后操作 2. Maven 项目 1)所有配置项 2)Build ...
- 所谓 ICMP,不过将军与士卒而已
什么是 ICMP 协议 关于这点我们在 IP 协议那篇文章中提过一嘴,IP 协议作为一种提供不可靠数据交付的网络层协议,在传输的过程中,其 IP 数据报可能会发生丢失.重复.延迟和乱序等各种情况, 但 ...
- 1036 Boys vs Girls
This time you are asked to tell the difference between the lowest grade of all the male students and ...