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. java面试-synchronized底层实现机制

    一.synchronized的三种应用方式 1.修饰实例方法,锁是当前实例对象,进入同步代码前要获得当前实例的锁 /** * synchronized修饰实例方法,当前线程的锁是实例对象account ...

  2. 华为云PB级数据库GaussDB(for Redis)揭秘第七期:高斯Redis与强一致

    摘要:在KV数据库领域,"强一致性"不仅是一个技术名词,它更是业务与运维的重要需求. 清明刚过,五一假期就要来了.大好春光,不如去婺源看油菜花吧!小云迅速打开APP刷出余票2张,赶 ...

  3. Leedcode算法专题训练(分治法)

    归并排序就是一个用分治法的经典例子,这里我用它来举例描述一下上面的步骤: 1.归并排序首先把原问题拆分成2个规模更小的子问题. 2.递归地求解子问题,当子问题规模足够小时,可以一下子解决它.在这个例子 ...

  4. Spring Boot demo系列(四):Spring Web+Validation

    2021.2.24 更新 1 概述 本文主要讲述了如何使用Hibernate Validator以及@Valid/@Validate注解. 2 校验 对于一个普通的Spring Boot应用,经常可以 ...

  5. vue中利用.env文件存储全局环境变量,以及配置vue启动和打包命令

    目录 1,前言 2,.env文件的作用 3,配置.env文件 4,配置启动命令 5,获取.env中的全局变量 5,实际用处 1,前言 分享一下vue项目中利用.env文件存储全局环境变量,以及利于项目 ...

  6. Linux安装MySQL8高版本压缩包(通用)

    前言 前段时间领导让我部署测试环境,希望安装高版本的MySQL,过程遇到很多问题,特此记录帮助迷失的人们 下载 MySQL官方下载地址:https://dev.mysql.com/downloads/ ...

  7. vue页面之间数据的传递

    vue是由一个个组件组合而成的页面,今天我们就来说一下页面之间数据的传递. 我们经常会在后台管理系统看到用户详情,有添加用户和编辑用户.有时候我们的添加和编辑是在同一页面上以模态框的形式展现的,但有的 ...

  8. mac系统 PHP Nginx环境变量修改

    场景:php默认的环境变量不是我们实际工作中想要的 执行命令:which php 查看默认的php指向的目录 :  /usr/bin/php 修改· ~/.bash_profile 文件 添加php环 ...

  9. 【golang】golang中结构体的初始化方法(new方法)

    准备工作: 定义结构体:Student import ( "fmt" "reflect") type Student struct { StudentId st ...

  10. DVWA之Command injection(命令执行漏洞)

    目录 Low Medium Middle Impossible 命令执行漏洞的原理:在操作系统中, &  .&& .|  . ||   都可以作为命令连接符使用,用户通过浏览器 ...