发布时间:2023-02-08 文章分类:编程知识 投稿人:王小丽 字号: 默认 | | 超大 打印

Spring注解驱动

文章来源:yuque.com/zuihoudewu/java_note/gwtgt9#ip308

@Cofigretion(proxyBeanMethods = true)

标记在类上,告诉spring这是一个配置类

首先引出两个概念:Full 全模式Lite 轻量级模式

Full(proxyBeanMethods = true) :proxyBeanMethods参数设置为true时即为:Full 全模式。 该模式下注入容器中的同一个组件无论被取出多少次都是同一个bean实例,即单实例对象,在该模式下SpringBoot每次启动都会判断检查容器中是否存在该组件 Lite(proxyBeanMethods = false) :proxyBeanMethods参数设置为false时即为:Lite 轻量级模式。该模式下注入容器中的同一个组件无论被取出多少次都是不同的bean实例,即多实例对象,在该模式下SpringBoot每次启动会跳过检查容器中是否存在该组件 什么时候用Full全模式,什么时候用Lite轻量级模式? 当在你的同一个Configuration配置类中,注入到容器中的bean实例之间有依赖关系时,建议使用Full全模式 当在你的同一个Configuration配置类中,注入到容器中的bean实例之间没有依赖关系时,建议使用Lite轻量级模式,以提高springboot的启动速度和性能

proxyBeanMethods 属性默认值是 true, 也就是说该配置类会被代理(CGLIB),在同一个配置文件中调用其它被 @Bean 注解标注的方法获取对象时会直接从 IOC 容器之中获取;

@Bean(value,initMethod,destroyMethod)

标记于方法上,将返回值注册进sping,id默认是方法名,可以使用value进行更名。init指定返回值类的初始化方法,destroy指定bean销毁方法

@ComponentScan(value[],excludeFilters{},includeFilters{})

\textcolor{#f08080}{标记在类上,开启注解扫描。excludeFilters和includeFilters根据书写顺序层层过滤}

  1. value 需要扫描的包

  2. excludeFilters={ 指定规则不扫描特定包

    @Filter(type=FilterType.ANNOTATION,classes={Controller.class})}

    FilterType.Annotation:按照定义的classes规则不扫描指定注解标注的类。

  3. includeFilters={同上,useDefaultFilters=false} 指定规则只扫描特定包

useDefaultFilters=false:将默认的全部扫描规则进行关闭,才能达到只扫描指定注解标注类的效果

  1. FilterType.ASPectj: 使用aspectj表达式

FilterType.REgex:使用正则表达式

FilterType.custom:使用自定义规则 自己编写类实现指定接口重写方法

  1. @Controller、@Component、@Service、@Repository。

@Scope(value)

\textcolor{#f08080}{标注方法或者类上,设置Bean的作用域}

  1. single:单实例(默认值)ioc容器启动时加载 以后每次获取都是从容器中获取

  2. prototype:多实例 获取Bean时才会创建对象 每次都是新的对象

  3. request:同一次请求创建一个实例

  4. session:同一次会话创建一个实例

@Lazy

\textcolor{#f08080}{懒加载,可标注在类,方法,全局变量,构造函数,形参}

作用:单实例Bean在ioc容器启动时不进行加载,获取Bean时再加载,并且往后每次也是同一个Bean

@Conditional

\textcolor{#f08080}{标记在类和方法上,根据一定条件判断,是否将Bean注册进ioc容器 放在类类上将控制整个类的实现。}

@Import(values[])

\textcolor{#f08080}{标记在类上,快速给容器导入Bean组件,id默认是组件带包全名}

  1. value:类名.class 将类注册进ioc容器 默认id是类全名

  2. 实现指定ImportSelector的类名.class:重写方法的返回值(new String[] {“类的全名”,“全名2”...})一次性导入多个组件

  3. 实现ImportBeanDefinitionRegister接口的类名.class:重写方法,调用register.registerBeanDefinition(name,new RootBeanDefafinition(类名.class))进行Bean的注册 可以自定义Bean的属性(scope和id)

<u>2,3 可以对Bean的注册,进行逻辑判断</u>

FactoryBean< T >接口

工厂bean,实现两个方法,1:getObject() 将返回值 注册bean进ioc (通过getBean(工厂Bean的id名)获取到的是被该方法注册的Bean 使用$工厂Bean的id名 才能获取到工厂Bean ) ,2:isSingleton ( return true) true为单实例 默认值

Bean的生命周期

  1. 单个Bean实现两个接口

    1. InitializingBean(重写方法 定义初始化逻辑 )早于init-method的执行

    2. DisposableBean接口(重写方法 定义销毁逻辑) 早于destroy-method的执行

  2. 单个Bean使用JSR250 的两个注解 (Bean不需要实现接口,只能作用于方法上

    1. @PostConstruct 在bean创建完成并属性赋值完成,未初始化间 在initializingBean 前

    2. @PreDestroy 在容器销毁bean之前通知进行清理工作

  3. 配置Bean后处理器 类实现BeanPostProcessor 重写两个方法

    Bean后处理器将作用于当前配置文件中所有的Bean。需要加入到容器中@Configuration

    1. postProcessBeforeInitialization 作用于Bean初始化前 (postConstruct前)

    2. postProcessAfterInitialization 作用于Bean初始化后(使用bean前)

需要注意的:

Spring 根据Bean的作用域来选择管理方式。

spring注解

@PropertySource(value["classpath:/路径"])

作用在类上,导入外部配置文件 (会将配置文件中的K/v 保存进运行环境变量中 可通过application.environment().getProperty("key")取对应的值)

@Value()

作用在类,方法,全局属性,方法形参

  1. 基本数据类型 string int

  2. 可以写spel ; #{20-2}

  3. 可以写${}; 搭配@propertySource注解使用(properties,yml)取出配置文件中的值(在运行环境变量中的值)

@Autowired @Qualifier

作用于构造方法上,方法上,形参上,属性上,注解上。

  1. 该注解有一个required属性,默认值是true,表示在注入的时候要求被注入的Bean必须是存在的,如果不存在则报错

  2. 如果使用@Autowired进行自动装配的接口有多个实现类,会报受检异常。此时必须将@Autowired注解和@Qualifier注解联合起来根据名称进行装配,在@Qualifier注解中指定Bean名称。

@Resource

@Resource注解用在属性上、setter方法上。

@Resource注解默认根据名称装配byName如果byname为空则根据类型查找

@Profile(value,default)

作用在类和方法上,环境标识表示指定组件在哪种(value)环境下才能注册到容器中,default设定默认加载

AOP

切入点表达式 execution

  1. execution( [访问控制权限修饰符] 返回值类型 [全限定类名]方法名(形式参数列表) [异常])

  2. [ ]中的内容是可选项,其余必填

  3. service包下所有的类中以delete开始的所有方法
    execution(public * com.powernode.mall.service.*.delete*(..))
  4. mall包下所有的类的所有的方法 两个点“..”代表当前包以及子包下的所有类。
    execution(* com.powernode.mall..*(..))

@Pointcut(execution)

作用于方法上,抽取公共的切入点表达式,本类中直接引用方法名,其他类中引用需要填带包全类名

@Pointcut("execution(* com.powernode.spring6.service.OrderService.*(..))")
public void pointcut(){}
----------------本类中以方法名引用------------------------------------
@Around("()")
public void aroundAdvice(){
System.out.println("环绕通知开始");}
----------------其他类中引用需要填带包全类名----------------------------

@Around("com.powernode.mall.类名.pointcut()")
public void aroundAdvice(){
System.out.println("环绕通知开始");}

基于AspectJ的AOP注解式开发

  1. 第一步:定义目标类以及目标方法(记得添加core,aspectj,aop依赖)

  2. 第二步:定义切面类 切面类加注解@Aspect 告诉ioc这是切面类

  3. 第三步:目标类和切面类都纳入spring bean管理 使用@Configuration + @Bean

  4. 第四步:在spring配置类上添加 @Enable Aspect JAutoProxy 开启基于注解的aop功能

  5. 第五步:在切面类中添加通知

  6. 第六步:在通知上添加切点表达式

@EnableAspectJAutoProxy(proxyTargetClass = true)

作用在类上,表示开启开启基于注解的aop功能

proxy-target-class="true" 表示采用cglib动态代理。 底层采用继承的方式实现。所以被代理的目标类不能使用final修饰。 需要引入它的依赖: 它既可以代理接口,又可以代理类

proxy-target-class="false" 表示采用jdk动态代理。默认值是false。即使写成false,当没有接口的时候,也会自动选择cglib生成代理类。 只能代理接口。

@Order(int)

可标注在方法,类,属性上,用于提高优先级,数字越小优先级越高

例如:可以使用@Order注解来标识切面类,为@Order注解的value指定一个整数型的数字,数字越小,优先级越高

事务

事务属性

事务中的重点属性:

一共有七种传播行为:

@Transactional(propagation = Propagation.REQUIRED)

在代码中设置事务的传播行为:
@Transactional(propagation = Propagation.REQUIRED)

注解实现事务

@EnableTransactionManagement

  1. 第一步:在spring配置文件中开启基于注解的事务管理功能。@Configration

  2. 第二步:导入依赖,通过@Bean配置数据源,注册事务管理器进容器中

@Transactional

  1. 第三步:给方法上添加@Transactional 表示当前方法开启事务管理

事务的隔离级别

事务隔离级别类似于教室A和教室B之间的那道墙,隔离级别越高表示墙体越厚。隔音效果越好。

数据库中读取数据存在的三大问题:(三大读问题)

事务隔离级别包括四个级别:

大家可以通过一个表格来记忆:

大家可以通过一个表格来记忆:

隔离级别 脏读 不可重复读 幻读
读未提交
读提交
可重复读
序列化

在Spring代码中如何设置隔离级别?

隔离级别在spring中以枚举类型存在:

spring注解

@Transactional(isolation = Isolation.READ_COMMITTED)

@Transactional(isolation = Isolation.READ_COMMITTED)

事务超时

@Transactional(timeout = 10)

以上代码表示设置事务的超时时间为10秒。

表示超过10秒如果该事务中所有的DML语句还没有执行完毕的话,最终结果会选择回滚。

默认值-1,表示没有时间限制。

这里有个坑,事务的超时时间指的是哪段时间?

在当前事务当中,最后一条DML语句执行之前的时间。如果最后一条DML语句后面很有很多业务逻辑,这些业务代码执行的时间不被计入超时时间。

当然,如果想让整个方法的所有代码都计入超时时间的话,可以在方法最后一行添加一行无关紧要的DML语句。

只读事务

@Transactional(readOnly = true)

将当前事务设置为只读事务,在该事务执行过程中只允许select语句执行,delete insert update均不可执行。

该特性的作用是:启动spring的优化策略。提高select语句执行效率。

如果该事务中确实没有增删改操作,建议设置为只读事务。

@Transactional(rollbackFor = RuntimeException.class)

设置哪些异常回滚事务:表示只有发生RuntimeException异常或该异常的子类异常才回滚

@Transactional(noRollbackFor = NullPointerException.class)

设置哪些异常不回滚事务: 表示发生NullPointerException或该异常的子类异常不回滚,其他异常则回滚。

@WebMvc

作用在类上,结合类实现HttpServlet,作用:代替xml配置方式。 同理@WebFIlter,@WebListener都是

@EnableWebMvc

作用在类上,代替xml定制mvc。标记的类实现WebMvcConfigurerAdapter抽象类,通过实现其方法进行,开启静态资源放行,设置视图解析器,配置拦截器等。