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 ...
随机推荐
- 结对编程_stage2
项目 内容 这个作业属于哪个课程 2021春季软件工程(罗杰 任健) 这个作业的要求在哪里 结对项目-第二阶段 我在这个课程的目标是 从实践中学习软件工程相关知识(结构化分析和设计方法.敏捷开发方法. ...
- Cube painting UVA - 253
We have a machine for painting cubes. It is supplied with three different colors: blue, red and gre ...
- 三维 WebGIS 新玩具:OpenGlobus
代码仓库地址:https://github.com/openglobus/openglobus 原创.@秋意正寒 目录 1 简介 2 HelloGlobus 3 在 Vite 中与 vue3 集成 4 ...
- .Net之配置文件
1. 说明 默认情况下读取配置Configuration的默认优先级:ConfigureAppConfiguration(自定义读取)>CommandLine(命令行参数)>Environ ...
- HIT手 | 机械电气构造简述和微分运动学及静力学的简单推导
机械结构电气构造简述 HIT手有四个手指,每个手指4个关节,其中第一和第二个关节正交,第三和第四个关节机械耦合,故只有3个自由度,另外大拇指多了一个相对手掌运动的自由度,故一只手掌总共有13各个自 ...
- 【Feign/Ribbon】记录一次生产上的SpringCloudFeign的重试问题
在上周在的微供有数项目中(数据产品),需要对接企业微信中第三方应用,在使用Feign的去调用微服务的用户模块用微信的code获取access_token以及用户工厂信息时出现Feign重试超时报错的情 ...
- POJ3040给奶牛发工资
题意: 有n种硬币,每种硬币有mi个,然后让你给奶牛发工资,每周发至少c元(就是不找零钱的意思)然后问你能发几周?(硬币之间都是倍数关系) 思路: 这个题目做了两天,丢脸,看完 ...
- Android系统自带的android.util.Base64的实现源码
由于Android逆向还原的时候,经常需要用到android.util.Base64的代码,因此从Android 4.4.4的 系统里抠出来进行备份,懒得用其他的代码进行修改替换了. /* * Cop ...
- [CTF]盲文对照表
[CTF]盲文对照表 摘自:https://wenku.baidu.com/view/28b04fd380eb6294dd886ca7.html 学点盲文 盲文又称点字,国际通用的点字由6个凸起的圆点 ...
- android The content of the adapter has changed but ListView did not receive a notification 错误的解决方案
使用了AsyncTask在后台刷新适配器,并且通知ui线程更新ListView,运行时发现时不时的出现 如题 的错误, 导致程序崩溃,解决方法如下: 1.建立一个缓冲数据集,这个数据集就是填充适配器的 ...