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学习 (核心)的更多相关文章

  1. iOS学习——核心动画

    iOS学习——核心动画 1.什么是核心动画 Core Animation(核心动画)是一组功能强大.效果华丽的动画API,无论在iOS系统或者在你开发的App中,都有大量应用.核心动画所在的位置如下图 ...

  2. iOS学习——核心动画之Layer基础

    iOS学习——核心动画之Layer基础 1.CALayer是什么? CALayer我们又称它叫做层.在每个UIView内部都有一个layer这样一个属性,UIView之所以能够显示,就是因为它里面有这 ...

  3. spark 入门学习 核心api

    spark入门教程(3)--Spark 核心API开发 原创 2016年04月13日 20:52:28 标签: spark / 分布式 / 大数据 / 教程 / 应用 4999 本教程源于2016年3 ...

  4. spring5学习笔记

    Spring5 框架概述 1.Spring 是轻量级的开源的 JavaEE 框架 2.Spring 可以解决企业应用开发的复杂性 3.Spring 有两个核心部分:IOC 和 Aop (1)IOC:控 ...

  5. ❀ Spring5学习大总结

    一.了解 Spring 基本介绍.主要思想 IoC/DI 1.了解 Spring 基本介绍 (1) Spring是什么? Spring 是一个轻量级的 DI/IoC 和 AOP 容器的开源框架,致力于 ...

  6. Linux学习-核心的编译与安装

    编译核心与核心模块 核心与核心模块需要先编译起来,而编译的过程其实非常简单,你可以先使用『 make help 』去查 阅一下所有可用编译参数, 就会知道有底下这些基本功能: [root@study ...

  7. Linux学习-核心编译的前处理与核心功能选择

    硬件环境检视与核心功能要求 根据自己的需求来确定编译的选项 保持干净原始码: make mrproper 我们还得要处理一下核心原始码底下的残留文件才行!假设我们是第一次 编译, 但是我们不清楚到底下 ...

  8. Linux学习-核心与核心模块

    谈完了整个开机的流程,您应该会知道,在整个开机的过程当中,是否能够成功的驱动我们主机的硬 件配备, 是核心 (kernel) 的工作!而核心一般都是压缩文件,因此在使用核心之前,就得要将他解 压缩后, ...

  9. Spring MVC学习------------核心类与接口

    核心类与接口: 先来了解一下,几个重要的接口与类. 如今不知道他们是干什么的没关系,先混个脸熟,为以后认识他们打个基础. DispatcherServlet   -- 前置控制器 HandlerMap ...

随机推荐

  1. 结对编程_stage2

    项目 内容 这个作业属于哪个课程 2021春季软件工程(罗杰 任健) 这个作业的要求在哪里 结对项目-第二阶段 我在这个课程的目标是 从实践中学习软件工程相关知识(结构化分析和设计方法.敏捷开发方法. ...

  2. Cube painting UVA - 253

     We have a machine for painting cubes. It is supplied with three different colors: blue, red and gre ...

  3. 三维 WebGIS 新玩具:OpenGlobus

    代码仓库地址:https://github.com/openglobus/openglobus 原创.@秋意正寒 目录 1 简介 2 HelloGlobus 3 在 Vite 中与 vue3 集成 4 ...

  4. .Net之配置文件

    1. 说明 默认情况下读取配置Configuration的默认优先级:ConfigureAppConfiguration(自定义读取)>CommandLine(命令行参数)>Environ ...

  5. HIT手 | 机械电气构造简述和微分运动学及静力学的简单推导

      机械结构电气构造简述 HIT手有四个手指,每个手指4个关节,其中第一和第二个关节正交,第三和第四个关节机械耦合,故只有3个自由度,另外大拇指多了一个相对手掌运动的自由度,故一只手掌总共有13各个自 ...

  6. 【Feign/Ribbon】记录一次生产上的SpringCloudFeign的重试问题

    在上周在的微供有数项目中(数据产品),需要对接企业微信中第三方应用,在使用Feign的去调用微服务的用户模块用微信的code获取access_token以及用户工厂信息时出现Feign重试超时报错的情 ...

  7. POJ3040给奶牛发工资

    题意:       有n种硬币,每种硬币有mi个,然后让你给奶牛发工资,每周发至少c元(就是不找零钱的意思)然后问你能发几周?(硬币之间都是倍数关系) 思路:       这个题目做了两天,丢脸,看完 ...

  8. Android系统自带的android.util.Base64的实现源码

    由于Android逆向还原的时候,经常需要用到android.util.Base64的代码,因此从Android 4.4.4的 系统里抠出来进行备份,懒得用其他的代码进行修改替换了. /* * Cop ...

  9. [CTF]盲文对照表

    [CTF]盲文对照表 摘自:https://wenku.baidu.com/view/28b04fd380eb6294dd886ca7.html 学点盲文 盲文又称点字,国际通用的点字由6个凸起的圆点 ...

  10. android The content of the adapter has changed but ListView did not receive a notification 错误的解决方案

    使用了AsyncTask在后台刷新适配器,并且通知ui线程更新ListView,运行时发现时不时的出现 如题 的错误, 导致程序崩溃,解决方法如下: 1.建立一个缓冲数据集,这个数据集就是填充适配器的 ...