Spring IOC 和 AOP
Spring
创建的类在spring 中的生命周期, 控制权限交给了spring处理,抛弃了之前手动创建对象和实例对象。
bean容器: 一个对象被创建和被实例化的过程发生的事。
myclass --> 推断构造器 --> 初始化前 --> 初始化中 --> 初始化后 --> 代理对象aop --> (IOC bean)单例池 --> Bean对象
spring的特性:
控制反转 inversion of control : 指将对象的创建权力交给spring控制,每个对象称为bean
依赖注入 dependency injection : 依赖的对象不需要手动调用setxxx方法去设置,而是通过配置赋值
面向切面编程 aspect oriented programming : 在spring初始化实例对象前,通过切面设置,可以执行指定的切面方法。
spring容器: spring它是一个容器,我们的对象的生命周期在spring容器中控制着。
组件化:使用简单的组件配置组合成一个复杂的应用。在 Spring 中可以使用XML和Java注解组合这些对象。
其他概念:
单例: 一个类只有一个实例对象,实例化对象后将提供整系统使用。 bean是单例池,在多线程中,每个bean对象都只能存在一个单线中!
同步机制:
ThreadLocal和线程同步机制相比有什么优势呢?他们都是为了解决多线程中相同变量的访问冲突问题。在同步机制中,通过对象的锁机制保证同一时间只有一个线程访问变量。这时该变量是多个线程共享的,使用同步机制要求程序慎密地分析什么时候对变量进行读写,什么时候需要锁定某个对象,什么时候释放对象锁等繁杂的问题,程序设计和编写难度相对较大。
概括起来说,对于多线程资源共享的问题,同步机制采用了“以时间换空间”的方式,而ThreadLocal采用了“以空间换时间”的方式。前者仅提供一份变量,让不同的线程排队访问,而后者为每一个线程都提供了一份变量,因此可以同时访问而互不影响。
spring核心:
1 控制反转 inversion of control
为什么要使用控制反转:
bean对象变得灵活,应用对象的创建的权力交给spring管理,用户可以通过spring容器获取应用对象。
减少耦合度
实现的方式有哪些?
依赖注入DI:
构造函数的依赖注入
设值函数的依赖注入
注入内部beans
注入集合
推断构造方法(默认的无参构造法)
Setter方法注入
使用xml配置应用对象
1.1 Bean
定义: bean是一个被实例化组装,通过springioc管理的对象,并由容器提供的配置 元数据 创建的。
bean的属性参数:
属性 | 描述 |
---|---|
class | 这个属性是强制性的,并且指定用来创建 bean 的 bean 类。 |
name 起别名(name= a b c ..)可多个 | 这个属性指定唯一的 bean 标识符。在基于 XML 的配置元数据中,你可以使用 ID 和/或 name 属性来指定 bean 标识符。 |
scope | 这个属性指定由特定的 bean 定义创建的对象的作用域,它将会在 bean 作用域的章节中进行讨论。 |
constructor-arg | 它是用来注入依赖关系的,并会在接下来的章节中进行讨论。 |
properties | 它是用来注入依赖关系的,并会在接下来的章节中进行讨论。 |
autowiring mode | 它是用来注入依赖关系的,并会在接下来的章节中进行讨论。 |
lazy-initialization mode | 延迟初始化的 bean 告诉 IoC 容器在它第一次被请求时,而不是在启动时去创建一个 bean 实例。 |
initialization 方法 | 在 bean 的所有必需的属性被容器设置之后,调用回调方法。它将会在 bean 的生命周期章节中进行讨论。 |
destruction 方法 | 当包含该 bean 的容器被销毁时,使用回调方法。它将会在 bean 的生命周期章节中进行讨论。 |
ref | 引入内部bean对象 |
配置bean元数据的方式:
- 基于 XML 的配置文件
- 基于注解的配置
- 基于 Java 的配置
bean的后置处理器
在初始化bean的前后对bean进行其他处理
如何做后置处理:
继承BeanPostProcessor 接口 实现初始化 前和初始化后方法。
public class InitHelloWorld implements BeanPostProcessor {
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("BeforeInitialization : " + beanName);
return bean; // you can return any other object as well
}
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("AfterInitialization : " + beanName);
return bean; // you can return any other object as well
}
}
bean的作用域
通过配置xml 中的 scope 指定哪种作用域
作用域 | 描述 |
---|---|
singleton | 在spring IoC容器仅存在一个Bean实例,Bean以单例方式存在,默认值 |
prototype | 每次从容器中调用Bean时,都返回一个新的实例,即每次调用getBean()时,相当于执行newXxxBean() |
request | 每次HTTP请求都会创建一个新的Bean,该作用域仅适用于WebApplicationContext环境 |
session | 同一个HTTP Session共享一个Bean,不同Session使用不同的Bean,仅适用于WebApplicationContext环境 |
global-session | 一般用于Portlet应用环境,该作用域仅适用于WebApplicationContext环境 |
基于xml配置bean对象
<?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
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="" class=""
scope="">
</bean>
</beans>
import
当有多个bean.xml配置文件时,可以通过总的application.xml文件用Import到管理多个bean.xml文件
application.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
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<import resource="bean.xml"/>
<import resource="bean1.xml"/>
</beans>```
2 依赖注入
给bean对象赋值元数据,元数据可以是引用class (注入内部Bean),有参构造方法,普通元数, 集合等复杂的数据赋值。
基本注入
2.1 有参构造方法
2.2 内部Bean注入
2.3 普通参数注入
2.4 集合参数注入
set , map ,array , 属性propr, null
类元数据
private String beanname;
private BeanLife beanLife; //内部Bena注入
//集合注入
private Set<String> setdi;
private Map<String,String> mapdi;
private String[] arrayListdi;
private String nulldi;
private Properties propertiesdi;
<?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
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
内部bean
<bean id="beanLife" class="spring.bean.BeanLife"/>
<bean id="beanDI" class="spring.bean.BeanDI">
<!--基本参数-->
<property name="beanname" value="hellobean"/>
<!-- 内部bean-->
<property name="beanLife" ref="beanLife"/>
<!-- 集合-->
set
<property name="setdi">
<set>
<value>set值</value>
<value>set值1</value>
</set>
</property>
map
<property name="mapdi">
<map>
<entry key="用名" value="root"></entry>
<entry key="密码" value="root"></entry>
</map>
</property>
数组
<property name="arrayListdi">
<array>
<value>西县及</value>
<value>数组类型</value>
</array>
</property>
null
<property name="nulldi">
<null/>
</property>
属性propety
<property name="propertiesdi">
<props>
<prop key="one">INDIA</prop>
<prop key="two">Pakistan</prop>
<prop key="three">USA</prop>
<prop key="four">USA</prop>
</props>
</property>
</bean>
</beans>
简化注入
2.5 p 标签注入
xmlns:p="http://www.springframework.org/schema/p" 引入
属性命名空间注入
传统的属性参数 property name = "pname" value ="valuename" === p:pname="valuename"
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
传统属性注入
<bean name="classic" class="com.example.ExampleBean">
<property name="email" value="someone@somewhere.com"/>
</bean>
p命名注入
<bean name="p-namespace" class="com.example.ExampleBean"
p:email="someone@somewhere.com"/>
注入的是内部bean对象时 p:spouse-ref
<bean name="classic" class="com.example.ExampleBean"
p:name = "Jane Doe" p:spouse-ref = "user"
>
<bean name="user" class="com.example.User">
<property name="name" value="Jane Doe"/>
</bean>
</beans>
2.6 c 标签注入
配置有参构造函数参数注入
xmlns:c="http://www.springframework.org/schema/c"
<!-- 使用c p 标签简化注入-->
<bean id="userBean" class="spring.bean.UserBean" p:beanname="helloUserBean" c:beanname="有参构造"/>
2.7 depends-on
用来指定多个内部bean对象
depends-on 属性既可以指定初始化时间依赖,也可以指定对应的销毁时间依赖(仅在单例 bean 的情况下)。 与给定 bean 定义依赖关系的依赖 bean 首先被销毁,在给定 bean 本身被销毁之前。 因此,depends-on 也可以控制关闭顺序。
<bean id="beanOne" class="ExampleBean" depends-on="bean1,bean2">
<property name="manager" ref="manager" />
</bean>
<bean id="bean1" class="ManagerBean" />
<bean id="bean2" class="x.y.jdbc.JdbcAccountDao" />
3.自动装配 autowired
没有自动装配之前,我们用xml配置内部Bean对象属性,通过 ref 或者p标签 p:spouse-ref,引入内部Bena的元数据。
现在用自动装配 autowired="byName/byType" ,自己去容器找到内部类的属性名和类型。
byName:内部bean对象属性名
byType: 内部bean对象数据类型
<!-- 自动装配-->
两个内部类
<bean id="man" class="spring.bean.userclass.Man"/>
<bean id="gegir" class="spring.bean.userclass.Gegir"/>
bean对象
<bean id="proson" class="spring.bean.userclass.Proson" p:name="人们" autowire="byType">
</bean>
构造函数的自动装配 constructor-arg
<!-- 自动装配-->
<bean id="man" class="spring.bean.userclass.Man"/>
<bean id="gegir" class="spring.bean.userclass.Gegir"/>
<bean id="proson" class="spring.bean.userclass.Proson" p:name="人们" autowire="constructor">
<constructor-arg value="这是man构造函数"/>
<constructor-arg value="这是gegir构造函数"/>
</bean>
4.面向切面AOP
面向切面是基于动态代理的反射机制,通过创建代理对象,可以将方法切入到指定目标类方法前后,或者环绕,或者抛异常
创建aop的方法有哪些
原生的spring api
基于 bean.xml 配置文件
基于注解
什么是切面(<aop:aspect ref="日志类"> 自定义的切入面)
切入目标类的,代理类
什么是切点(expression="execution(* aop.serve.UserServceImp.*(..)))又是实现类
切入点是被代理类的方法执行的目标类
每个类执行完方法之前和之后切入面类的方法就会根据应用场景来执行你方法的前后通知
依赖Spring5的AOP依赖
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.2</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.1.RELEASE</version>
</dependency>
基于xml配置实现AOP
场景:
我有一个数据库操作的业务类,它继承了userDao并实现增删改查方法,userDaoImp继承类执行sql的业务操作。 我想在执行sql操作的前后都加一个通过,执行中,和执行完成
UserDao.interface
package aop.dao;
public interface UserDao {
public void add();
public void delete();
public void update();
public void select();
public void insert();
}
UserServceImp.class
package aop.serve;
import aop.dao.UserDao;
public class UserServceImp implements UserDao {
@Override
public void add() {
System.out.println("执行添加操作");
}
@Override
public void delete() {
System.out.println("删除");
}
@Override
public void update() {
System.out.println("更新");
}
@Override
public void select() {
System.out.println("查询");
}
@Override
public void insert() {
System.out.println("插入");
}
}
切面类Logger.class
public class Logger {
public void befor(){
System.out.println("正在执行操作!");
}
public void after(){
System.out.println("执行完成!");
}
}
<?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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd ">
注入bean对象
<bean id="userServceImp" class="aop.serve.UserServceImp"/>
<bean id="logger" class="aop.log.Logger"/>
配置aop
<aop:config>
<!--自定义的日志切面-->
<aop:aspect ref="logger">
<aop:pointcut id="pointcut" expression="execution(* aop.serve.UserServceImp.*(..))"/>
<aop:before method="befor" pointcut-ref="pointcut"/>
<aop:after method="after" pointcut-ref="pointcut"/>
</aop:aspect>
</aop:config>
</beans>
execution( * * * * ) 五个 * 号所代表的含义
execution( 返回值类型 切点类路径 子包 所有类 所有方法)
符号 | 含义 |
---|---|
execution() | 表达式的主体; |
1 第一个”*“符号 | 表示返回值的类型任意; |
2 com.sample.service.impl | AOP所切的服务的包名,即,我们的业务部分 |
3 包名后面的”..“ | 表示当前包及子包 |
4 第二个”*“ | 表示类名,*即所有类。此处可以自定义,下文有举例 |
5 .*(..) | 表示任何方法名,括号表示参数,两个点表示任何参数类型 |
Spring注解
一 IOC注解
简化之前的bean.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
开启注解模式
<context:annotation-config/>
</beans>
Bean (@component )
@Component
等价于 xml 中的
标签 ,指定名称用 @component("user") ===
开启组件扫描
<context:component-scan base-package=“扫描包下带有component的类”/>
生命周期
作用域@Scope
@Scope(“singleton”):单例模式
@Scope(“prototype”):多例模式
依赖注入
普通参数的依赖注入@Value
注入集合
构造函数的注入
内部Bean对象的注入
自动装配 @Autowired @Resource
解决内部bean对象的byName属性名和byType类型,构造方法等元数据
@Resource
private Man man;
@Autowired
private Gegir gegir;
<!-- 开启注解模式-->
<context:annotation-config/>
autowired注解
<bean id="gegir1" class="spring.bean.userclass.Gegir"/>
resouce注解 javax自带的
<bean id="man" class="spring.bean.userclass.Man"/>
<bean id="man2" class="spring.bean.userclass.Man"/>
<bean id="proson" class="spring.bean.userclass.Proson"/>
@Autowired @Resourc的区别
- 功能相同都是用来自动装配的,都可以放在内部bean对象上
- @Autowired通过byname方法来实现
- @Resourc通过byname方法来实现,如果找不到属性名,则通过byType实现
其他注解
JSR250
bean的初始化 @PostConstruct 注释作为初始化回调函数的一个替代,
bean的销毁 @PreDestroy 注释作为销毁回调函数的一个替代
@Required 注解应用于 bean 属性的 setter 方法**
@Qualifier 指定bean.xml中使用的是哪某个beans对象
package com.tutorialspoint;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
public class Profile {
@Autowired
@Qualifier("student1") 指定bean.xml另外的byName值
private Student student;
public Profile(){
System.out.println("Inside Profile constructor." );
}
public void printAge() {
System.out.println("Age : " + student.getAge() );
}
public void printName() {
System.out.println("Name : " + student.getName() );
}
}
<?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
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:annotation-config/>
<!-- Definition for profile bean -->
<bean id="profile" class="com.tutorialspoint.Profile">
</bean>
<!-- 同个byTpye 不同byName -->
<bean id="student1" class="com.tutorialspoint.Student">
<property name="name" value="Zara" />
<property name="age" value="11"/>
</bean>
<bean id="student2" class="com.tutorialspoint.Student">
<property name="name" value="Nuha" />
<property name="age" value="2"/>
</bean>
</beans>
二 AOP注解
切点@Pointcut("execution(* 目标类路径 *(..))")
切面@Aspect
前置通知 @Before
后置通知 @After
环绕通知 @Around
最后环绕通知 @AfterReturning(pointcut = "", returning="返回值")
异常通知 @AfterThrowing(pointcut = "", throwing = "抛异常的参数")
实现
注入bean
<?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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd ">
<!--开启切面注解-->
<aop:aspectj-autoproxy/>
切面
<bean id="aLogger" class="aop.annotation.ALogger"/>
切点
<bean id="aUserDaoImp" class="aop.annotation.AUserDaoImp"/>
</beans>
日志注解切面
package aop.annotation;
import org.aspectj.lang.annotation.*;
@Aspect
public class ALogger {
单独抽取指向切点的方法供其他切面方法使用
@Pointcut("execution(* aop.annotation.AUserDaoImp.*(..))")
public void selecall(){}
@Before("selecall()")
public void befor(){
System.out.println("执行之前!");
}
@After("selecall()")
public void after(){
System.out.println("执行之后!");
}
public void aroutd(){ System.out.println("在方法之前之后,环绕通知");}
public void afterreturning(){
System.out.println("afterreturning");
}
@AfterThrowing(pointcut = "selecall()", throwing = "E")
public void throwing(IllegalArgumentException E){
System.out.println("throwing"+ E.toString());
}
}
切点
import org.springframework.stereotype.Component;
@Component
public class AUserDaoImp implements AUserDao{
@Override
public void add() {
System.out.println("执行添加操作");
}
@Override
public void delete() {
System.out.println("删除");
}
@Override
public void update() {
System.out.println("更新");
}
@Override
public void select() {
System.out.println("查询");
}
@Override
public void insert() {
System.out.println("插入");
}
}
Spring使用的注解大全和解释
注解 | 解释 |
---|---|
@Controller | 组合注解(组合了@Component注解),应用在MVC层(控制层),DispatcherServlet会自动扫描注解了此注解的类,然后将web请求映射到注解了@RequestMapping的方法上。 |
@Service | 组合注解(组合了@Component注解),应用在service层(业务逻辑层) |
@Reponsitory | 组合注解(组合了@Component注解),应用在dao层(数据访问层) |
@Component | 表示一个带注释的类是一个“组件”,成为Spring管理的Bean。当使用基于注解的配置和类路径扫描时,这些类被视为自动检测的候选对象。同时@Component还是一个元注解。 |
@Autowired | Spring提供的工具(由Spring的依赖注入工具(BeanPostProcessor、BeanFactoryPostProcessor)自动注入。) |
@Resource | JSR-250提供的注解 |
@Inject | JSR-330提供的注解 |
@Configuration | 声明当前类是一个配置类(相当于一个Spring配置的xml文件) |
@ComponentScan | 自动扫描指定包下所有使用@Service,@Component,@Controller,@Repository的类并注册 |
@Bean | 注解在方法上,声明当前方法的返回值为一个Bean。返回的Bean对应的类中可以定义init()方法和destroy()方法,然后在@Bean(initMethod=”init”,destroyMethod=”destroy”)定义,在构造之后执行init,在销毁之前执行destroy。 |
@Aspect | 声明一个切面(就是说这是一个额外功能) |
@After | 后置建言(advice),在原方法前执行。 |
@Before | 前置建言(advice),在原方法后执行。 |
@Around | 环绕建言(advice),在原方法执行前执行,在原方法执行后再执行(@Around可以实现其他两种advice) |
@PointCut | 声明切点,即定义拦截规则,确定有哪些方法会被切入 |
@Transactional | 声明事务(一般默认配置即可满足要求,当然也可以自定义) |
@Cacheable | 声明数据缓存 |
@EnableAspectJAutoProxy | 开启Spring对AspectJ的支持 |
@Value | 值得注入。经常与Sping EL表达式语言一起使用,注入普通字符,系统属性,表达式运算结果,其他Bean的属性,文件内容,网址请求内容,配置文件属性值等等 |
@PropertySource | 指定文件地址。提供了一种方便的、声明性的机制,用于向Spring的环境添加PropertySource。与@configuration类一起使用。 |
@PostConstruct | 标注在方法上,该方法在构造函数执行完成之后执行。 |
@PreDestroy | 标注在方法上,该方法在对象销毁之前执行。 |
@Profile | 表示当一个或多个指定的文件是活动的时,一个组件是有资格注册的。使用@Profile注解类或者方法,达到在不同情况下选择实例化不同的Bean。@Profile(“dev”)表示为dev时实例化。 |
@EnableAsync | 开启异步任务支持。注解在配置类上。 |
@Async | 注解在方法上标示这是一个异步方法,在类上标示这个类所有的方法都是异步方法。 |
@EnableScheduling | 注解在配置类上,开启对计划任务的支持。 |
@Scheduled | 注解在方法上,声明该方法是计划任务。支持多种类型的计划任务:cron,fixDelay,fixRate |
@Conditional | 根据满足某一特定条件创建特定的Bean |
@Enable* | 通过简单的@Enable来开启一项功能的支持。所有@Enable注解都有一个@Import注解,@Import是用来导入配置类的,这也就意味着这些自动开启的实现其实是导入了一些自动配置的Bean(1.直接导入配置类2.依据条件选择配置类3.动态注册配置类) |
@RunWith | 这个是Junit的注解,springboot集成了junit。一般在测试类里使用:@RunWith(SpringJUnit4ClassRunner.class) — SpringJUnit4ClassRunner在JUnit环境下提供Sprng TestContext Framework的功能 |
@ContextConfiguration | 用来加载配置ApplicationContext,其中classes属性用来加载配置类:@ContextConfiguration(classes = {TestConfig.class(自定义的一个配置类)}) |
@ActiveProfiles | 用来声明活动的profile–@ActiveProfiles(“prod”(这个prod定义在配置类中)) |
@EnableWebMvc | 用在配置类上,开启SpringMvc的Mvc的一些默认配置:如ViewResolver,MessageConverter等。同时在自己定制SpringMvc的相关配置时需要做到两点:1.配置类继承WebMvcConfigurerAdapter类2.就是必须使用这个@EnableWebMvc注解。 |
@RequestMapping | 用来映射web请求(访问路径和参数),处理类和方法的。可以注解在类和方法上,注解在方法上的@RequestMapping路径会继承注解在类上的路径。同时支持Serlvet的request和response作为参数,也支持对request和response的媒体类型进行配置。其中有value(路径),produces(定义返回的媒体类型和字符集),method(指定请求方式)等属性。 |
@ResponseBody | 将返回值放在response体内。返回的是数据而不是页面 |
@RequestBody | 允许request的参数在request体中,而不是在直接链接在地址的后面。此注解放置在参数前。 |
@PathVariable | 放置在参数前,用来接受路径参数。 |
@RestController | 组合注解,组合了@Controller和@ResponseBody,当我们只开发一个和页面交互数据的控制层的时候可以使用此注解。 |
@ControllerAdvice | 用在类上,声明一个控制器建言,它也组合了@Component注解,会自动注册为Spring的Bean。 |
@ExceptionHandler | 用在方法上定义全局处理,通过他的value属性可以过滤拦截的条件:@ExceptionHandler(value=Exception.class)–表示拦截所有的Exception。 |
@ModelAttribute | 将键值对添加到全局,所有注解了@RequestMapping的方法可获得次键值对(就是在请求到达之前,往model里addAttribute一对name-value而已)。 |
@InitBinder | 通过@InitBinder注解定制WebDataBinder(用在方法上,方法有一个WebDataBinder作为参数,用WebDataBinder在方法内定制数据绑定,例如可以忽略request传过来的参数Id等)。 |
@WebAppConfiguration | 一般用在测试上,注解在类上,用来声明加载的ApplicationContext是一个WebApplicationContext。他的属性指定的是Web资源的位置,默认为src/main/webapp,我们可以修改为:@WebAppConfiguration(“src/main/resources”)。 |
@EnableAutoConfiguration | 此注释自动载入应用程序所需的所有Bean——这依赖于Spring Boot在类路径中的查找。该注解组合了@Import注解,@Import注解导入了EnableAutoCofigurationImportSelector类,它使用SpringFactoriesLoader.loaderFactoryNames方法来扫描具有META-INF/spring.factories文件的jar包。而spring.factories里声明了有哪些自动配置。 |
@SpingBootApplication | SpringBoot的核心注解,主要目的是开启自动配置。它也是一个组合注解,主要组合了@Configurer,@EnableAutoConfiguration(核心)和@ComponentScan。可以通过@SpringBootApplication(exclude={想要关闭的自动配置的类名.class})来关闭特定的自动配置。 |
@ImportResource | 虽然Spring提倡零配置,但是还是提供了对xml文件的支持,这个注解就是用来加载xml配置的。例:@ImportResource({“classpath |
@ConfigurationProperties | 将properties属性与一个Bean及其属性相关联,从而实现类型安全的配置。例:@ConfigurationProperties(prefix=”authot”,locations={“classpath |
@ConditionalOnBean | 条件注解。当容器里有指定Bean的条件下。 |
@ConditionalOnClass | 条件注解。当类路径下有指定的类的条件下。 |
@ConditionalOnExpression | 条件注解。基于SpEL表达式作为判断条件。 |
@ConditionalOnJava | 条件注解。基于JVM版本作为判断条件。 |
@ConditionalOnJndi | 条件注解。在JNDI存在的条件下查找指定的位置。 |
@ConditionalOnMissingBean | 条件注解。当容器里没有指定Bean的情况下。 |
@ConditionalOnMissingClass | 条件注解。当类路径下没有指定的类的情况下。 |
@ConditionalOnNotWebApplication | 条件注解。当前项目不是web项目的条件下。 |
@ConditionalOnResource | 条件注解。类路径是否有指定的值。 |
@ConditionalOnSingleCandidate | 条件注解。当指定Bean在容器中只有一个,后者虽然有多个但是指定首选的Bean。 |
@ConditionalOnWebApplication | 条件注解。当前项目是web项目的情况下。 |
@EnableConfigurationProperties | 注解在类上,声明开启属性注入,使用@Autowired注入。例:@EnableConfigurationProperties(HttpEncodingProperties.class)。 |
@AutoConfigureAfter | 在指定的自动配置类之后再配置。例:@AutoConfigureAfter(WebMvcAutoConfiguration.class) |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)