spring常用注解
ztj100 2025-05-11 19:43 3 浏览 0 评论
一、组件注解
1、@Component(“xxx”)
指定某个类是容器的bean,@Component(value="xx")相当于<bean id="xx" />,其中value可以不写。
用于标注类为spring容器bean的注解有四个,主要用于区别不同的组件类,提高代码的可读性:
a、@Component, 用于标注一个普通的bean
b、@Controller 用于标注一个控制器类(控制层 controller)
c、@Service 用于标注业务逻辑类(业务逻辑层 service)
d、@Repository 用于标注DAO数据访问类 (数据访问层 dao)
对于上面四种注解的解析可能是相同的,尽量使用不同的注解提高代码可读性。
注解用于修饰类,当不写value属性值时,默认值为类名首字母小写。
2、@Scope(“prototype”)
该注解和@Component这一类注解联合使用,用于标记该类的作用域,默认singleton。
也可以和@Bean一起使用,此时@Scope修饰一个方法。关于@Bean稍后有说明
3、@Lazy(true)
指定bean是否延时初始化,相当于<bean id="xx" lazy-init=""> ,默认false。@Lazy可以和@Component这一类注解联合使用修饰类,也可以和@Bean一起使用修饰方法
注:此处初始化不是指不执行init-method,而是不创建bean实例和依赖注入。只有当该bean(被@Lazy修饰的类或方法)被其他bean引用(可以是自动注入的方式)或者执行getBean方法获取,才会真正的创建该bean实例,其实这也是BeanFactory的执行方式。
4、@DepondsOn({“aa”,“bb”})
该注解也是配合@Component这类注解使用,用于强制初始化其他bean
@DepondsOn("other")
@Lazy(true)
@Controller
@Scope("prototype")
public class UserAction{
...............
}
上面的代码指定,初始化bean “userAction"之前需要先初始化“aa”和“bb”两个bean,但是使用了@Lazy(true)所以spring容器初始化时不会初始化"userAction” bean。
5、@PostConstructor和@PreDestroy
@PostConstructor和@PreDestroy这两个注解是j2ee规范下的注解。这两个注解用于修饰方法,spring用这两个注解管理容器中spring生命周期行为。
a、@PostConstructor 从名字可以看出构造器之后调用,相当于<bean init-method="">。就是在依赖注入之后执行
b、@PreDestroy 容器销毁之前bean调用的方法,相当于<bean destroy-method="">
6、@Resource(name=“xx”)
@Resource 可以修饰成员变量也可以修饰set方法。当修饰成员变量时可以不写set方法,此时spring会直接使用j2ee规范的Field注入。
@Resource有两个比较重要的属性,name和type
a、如果指定了name和type,则从Spring容器中找到唯一匹配的bean进行装配,找不到则抛出异常;
b、如果指定了name,则从spring容器查找名称(id)匹配的bean进行装配,找不到则抛出异常;
c、如果指定了type,则从spring容器中找到类型匹配的唯一bean进行装配,找不到或者找到多个,都会抛出异常;
d、如果既没有指定name,又没有指定type,则自动按照byName方式进行装配
如果没有写name属性值时
a、修饰成员变量,此时name为成员变量名称
b、修饰set方法,此时name 为set方法的去掉set后首字母小写得到的字符串
7、@Autowired(required=false)
@Autowired可以修饰构造器,成员变量,set方法,普通方法。@Autowired默认使用byType方式自动装配。required标记该类型的bean是否是必须的,默认为必须存在(true)。
可以配合@Qualifier(value="xx"),实现按beanName注入:
a、required=true(默认),为true时,从spring容器查找和指定类型匹配的bean,匹配不到或匹配多个则抛出异常
b、使用@Qualifier("xx"),则会从spring容器匹配类型和 id 一致的bean,匹配不到则抛出异常
@Autowired会根据修饰的成员选取不同的类型:
a、修饰成员变量。该类型为成员变量类型
b、修饰方法,构造器。注入类型为参数的数据类型,当然可以有多个参数
8、demo
业务逻辑层:
//service层,业务逻辑
@Service
public class UserService{
@Resource(name="userDao")
private UserDao userDao;
//@Autowired
//@Qualifier("userDao")
//private IUserDao userDao;
//相对来说使用`@Resource`更简单一些
.......实际业务.............
}
数据访问层:
//dao层,持久化
@Repository
@Lazy(true)
@Scope("singleton")
public class UserDao implements InitializingBean,DisposableBean{
public UserDao() {
System.out.println("constructor...................");
}
public List<User> listUsers(){
System.out.println("查询所有用户");
return null;
}
@PostConstruct
public void postConstructor() {
System.out.println("post_constructor.................");
}
//覆盖InitializingBean接口方法
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("after_properties_set..............");
}
@PreDestroy
public void after() {
System.out.println("pre_destroty.................");
}
//重写DisposableBean方法
@Override
public void destroy() throws Exception {
System.out.println("destry_method.............");
}
}
测试类:
//测试类
public class TestAnnotation{
@Test
public void test1(){
ClassPathXmlApplicationContext application=new ClassPathXmlApplicationContext("applicationContext.xml");
//配置文件里只有一行就是开启自动扫描” <context:component-scan base-package="com" /> “
System.out.println();
System.out.println("--------获取bean-----------");
System.out.println();
System.out.println(application.getBean("userDao"));
//关闭容器,就会销毁容器中的bean
application.close();
}
}
输出结果:
constructor...................
post_constructor.................
after_properties_set..............
--------获取bean-----------
com.dao.PersonManager@4872669f
pre_destroty.................
destry.............
pre_destroty.................
destry.............
可以看到虽然UserDao 使用@Lazy,但是还是在spring容器初始化的时候还是创建了UserDao实例。原因很简单,因为在UserService中需要注入UserDao,所以在此时创建的UserDao实例也属于延时初始化。
在上面我们还使用了两个接口InitializingBean 和DisposableBean,这两个接口用于管理singleton作用域的bean的生命周期,类似init-method和destroy-method。不同之处就是调用的循序不一致:
a、初始化调用顺序 :@PostConstructor > InitializingBean > init-method 用于指定bean依赖注入后的行为
b、销毁调用顺序 @PreDestroy > DisposableBean > destroy-method 用于定制bean销毁之前的行为
二、Aop相关注解
该注解是AspectJ中的注解,并不是spring提供的,所以还需要导入aspectjweaver.jar,aspectjrt.jar,除此之外还需要依赖aopalliance.jar
依赖包:
<dependency>
<groupId>aopalliance</groupId>
<artifactId>aopalliance</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.2</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.5.4</version>
</dependency>
UserDao.java
package com.example.aop;
import com.example.domain.User;
import org.springframework.stereotype.Repository;
import java.util.ArrayList;
import java.util.List;
@Repository
public class UserDao {
public UserDao() {
System.out.println("constructor...................");
}
public List<User> listUsers() {
System.out.println("查询所有用户");
return new ArrayList();
}
}
配置文件 applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
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-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<context:component-scan base-package="com" /> <!--自动扫描-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy><!--开启@AspectJ支持-->
</beans>
测试类:
public class TestAnnotation{
@Test
public void test1(){
ClassPathXmlApplicationContext application=new ClassPathXmlApplicationContext("applicationContext.xml");
//配置文件里只有一行就是开启自动扫描” <context:component-scan base-package="com" /> “
UserDao userDao = application.getBean("userDao",UserDao.class);
System.out.println("返回结果:\t"+userDao.listUsers());
}
}
1、@Aspect
修饰Java类,指定该类为切面类。当spring容器检测到某个bean被@Aspect修饰时,spring容器不会对该bean做增强处理(bean后处理器增强,代理增强)
package com.example.aop;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
@Component
@Aspect
public class UserAdvice{
}
2、@Before
修饰方法,before增强处理。用于对目标方法(切入点表达式表示方法)执行前做增强处理。可以用于权限检查,登陆检查。
常用属性:
value:指定切入点表达式 或者引用一个切入点
对com.example.aop 包下所有的类的所有方法做 before增强处理:
@Before(value = "execution(* com.example.aop.*(..)))")
public void before(JoinPoint joinPoint){
System.out.println("before 增强处理。。。。。。。。。。。。");
}
结果:
constructor…
before 增强处理。。。。。。。。。。。。
查询所有用户
返回结果: []
如果同一条切入点表达式被使用多次,可以使用更友好的方式。定义一个切入点:
@Pointcut("execution(* com.example.aop.*(..)))")
public void addLog(){}
@Before(value = "addLog()")
public void before(JoinPoint joinPoint){
System.out.println("before 增强处理。。。。。。。。。。。。");
}
增强方法可以接受一个JoinPoint 类型的参数,用于获取被执行目标方法的一下属性。
@Before(value = "addLog()")
public void execute(JoinPoint joinPoint){
System.out.println("before 增强处理。。。。。。。。。。。。");
System.out.println(Arrays.toString(joinPoint.getArgs()));
System.out.println(joinPoint.getKind());
System.out.println(joinPoint.getSignature().getName());
System.out.println(joinPoint.getSignature().getDeclaringTypeName());
System.out.println(joinPoint.getSignature().getDeclaringType());
System.out.println(joinPoint.getSignature().getModifiers());
System.out.println(joinPoint.getSourceLocation());
System.out.println(joinPoint.getTarget());
System.out.println(joinPoint.getThis());
}
结果:
constructor…
before 增强处理。。。。。。。。。。。。
[]
method-execution
listUsers
com.example.aop.UserDao
class com.example.aop.UserDao
1
org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint$SourceLocationImpl@15d49048
com.example.aop.UserDao@7098b907
com.example.aop.UserDao@7098b907
查询所有用户
3、@AfterReturning
修饰方法,afterreturning增强处理。目标方法正常结束后做增强处理。
常用属性:
a、pointcut/value:指定切入点表达式
b、returning:指定一个参数名,用于接受目标方法正常结束时返回的值。参数名称需要在增强方法中定义同名的参数。
注意:
a、如果使用了returning 。那么增强方法中的数据类型必须是返回结果的类型或者父类型,否则不会调用该增强处理。
b、使用了returning 还可以用来修改返回结果。
以上面的例子来说,目标方法返回结果类型应该满足下面的条件
returnResult instanceof List
修改返回值:
@AfterReturning(pointcut = "addLog()",returning = "list")
public void afterReturning(JoinPoint joinPoint,List list){
System.out.println("afterReturning..............");
System.out.println("afterReturning 接收结果。。。。。" + list);
//修改返回结果
list.add(new User(3L, "afterReturning......"));
}
结果:
constructor…
before 增强处理。。。。。。。。。。。。
查询所有用户
afterReturning…
afterReturning 接收结果。。。。。[]
接口返回结果: [User{id=3, name=‘afterReturning…’}]
可以看到 AfterReturning 修改了返回结果。
4、@AfterThrowing
修饰方法,afterthrowing增强处理。当目标程序方法抛出 异常或者异常无法捕获时,做增强处理。
常用属性:
a、pointcut/value :指定切入点表达式
b、throwing:指定一个形参,在增强方法中定义同名形参,用于访问目标方法抛出的异常
@AfterThrowing(pointcut = "addLog()",throwing = "e")
public void afterThrowing(JoinPoint joinPoint,Exception e){
System.out.println("afterThrowing..............");
System.out.println("抛出异常。。。。。"+e);
}
参数类型必须是 Throwable 的子类,同样也会有上面@AfterReturning 参数类型匹配的问题。
5、@After
修饰方法 ,after增强处理。无论方法是否正常结束,都会调用该增强处理(@After= @AfterReturning+@AfterThrowing)。但是该增强方式无法获取目标方法的返回结果,也获取目标方法抛出的异常。所以一般用于进行释放资源,功能类似于 finally。
常用属性:
a、value :指定切入点表达式
@After("addLog()")
public Object after(JoinPoint joinPoint) {
System.out.println("after..............");
//试图修改返回结果
List<User> list = new ArrayList<>();
list.add(new User(1L, "after....."));
return list;
}
结果:
constructor…
before 增强处理。。。。。。。。。。。。
查询所有用户
after…
afterReturning…
afterReturning 接收结果。。。。。[]
=接口返回结果: [User{id=3, name=‘afterReturning…’}]
从上面的结果来看 After 增加处理 ,因为不能接受返回结果作为参数,所以不能修改返回结果。
6、@Around
修饰方法, around增强处理。该处理可以目标方法执行之前和执行之后织入增强处理(@Before+@AfterReturning)。
Around增强处理通常需要在线程安全的环境下使用,如果@Before和@AfterReturning可以处理就没必要使用@Around。
常用属性:
a、value :指定切入点表达式
当定义一个Aound增前处理时,增强方法第一形参需要时ProceedingJoinPoint类型。ProceedingJoinPoint有一个Object proceed()方法,用于执行目标方法。当然也可以为目标方法传递数组参数,来修改目前方法的传入参数。
public interface ProceedingJoinPoint extends JoinPoint {
void set$AroundClosure(AroundClosure var1);
Object proceed() throws Throwable;
/**
* 修改目标方法的传参
*/
Object proceed(Object[] var1) throws Throwable;
}
around小结:
a、Around增强处理通常需要在线程安全的环境下使用
b、调用 proceed()可以获取返回结果,所以可以修改目标方法的返回值
c、proceed(Object[] var1) 可以修改入参,修改目标方法的入参
d、可以进行目标方法执行之前和执行之后织入增强处理
around 和 afterReturning 都可以修改返回结果。不过两者的原理不同:
a、around:可以任意修改,或者返回不相关的值。这个返回值完全可以自主控制
b、afterReturning,通过方法参数 ,使用对象引用的方式来修改对象。修改对象引用地址那么修改时无效的
除此之外从输出结果来看,增强处理是有序的:
around 和 afterReturning小结:
a、只有 around 和 afterReturning 可以获取并修改返回结果。需要注意两种方式修改的区别。
b、around 需要线程安全
c、虽然增强处理都需要 切入点表达式,并不是都支持 pointcut 属性,所以最好都是用value 属性指定。当注解只需要value属性时,value可以省略
@Before(value = "execution(* com.example.aop.*(..)))")
@Before("execution(* com.example.aop.*(..)))")
7、@Pointcut
修饰方法,定义一个切入点表达式用于被其他增强调用。使用该方式定义切入点方便管理,易复用。
切入点方法定义和测试方法定义类似,具有以下特点:
a、无返回值 (void)
b、无参数
c、方法体为空
d、方法名就是切入点名称
e、方法名不能为 execution
@Pointcut("execution(* user*(..))")
//使用一个返回值为void,空方法体的方法命名切入点。
//public 为修饰符,跟方法的修饰符一致,public 可以在其他切面类中使用该切点,default在同一个包下的切面类中使用该切点
//返回值必须为void , 方法名就是定义的切点名称
public void userAdvice(){}
切入点表达式
切入点表达式可以通过 &&、 ||、 ! 连接
1)、execution 表达式:
execution(* *(..)) // 匹配所有包及其子包下所有类的所有方法
execution(* com..*(..)) // 匹配com包及其子包下所有类的所有方法
execution(* com.example..*(..)) // 匹配com.example包及其子包下所有类的所有方法
execution(* com.example..get*(..)) // 匹配com.example包及其子包下所有类的所有get方法
execution(* com.example..*Controller.*(..)) //匹配com.example 包及其子包下,以Controller结尾的所有方法
2)、within 表达式:
a、匹配指定类下的所有方法。
b、匹配执行包及其子包下所有类的所有方法。
within(com.example..*) //匹配com.example包及其子包下所有类的所有方法
within(com.example.*) //匹配com.example包下所有类的所有方法(不包括子包)
within(com.example.aop.UserDao) //匹配 UserDao类下的所有方法
所以within可以看做execution的简写,不需要指定返回类型、方法名、参数(最小作用单位是类)
within(com..*)
execution(* com..*(..))
3)、@annotation:匹配使用指定注解修饰的目标方法;
@Before("@annotation(com.example.aop.CustomMethodAnnotation)")
匹配使用@CustomMethodAnnotation注解的目标方法。
4)、@within: 用于匹配使用指定注解修饰的类下的所有方法
within 作用范围是类,@within的作用范围与其一致。不同的是@within 指定的不是类而是注解
@Before("@within(org.springframework.web.bind.annotation.ResponseBody)")
匹配使用@ResponseBody 注解的类 下的所有方法。
不同的切入点表达式声明方式 顺序也是不同的:
AOP小结:
1)、Around增强处理通常需要在线程安全的环境下使用
2)、使用 around 和 afterReturning 可以获取并修改返回结果
3)、增强处理指定 切入点表达式时,最好使用value 属性
4)、切入点 名称(方法名)不能为 execution
5)、AfterReturning 指定了 returning属性接受目标方法返回结果,注意 参数类型需要和返回结果类型一致(满足 resutType instanceof argsType)
增强方式的顺序:
切入点表达式不同声明方式的顺序:
三、Java配置类相关注解
1、@Bean(name=“xxx”)
修饰方法,该方法的返回值为spring容器中管理的bean。当然该注解和上面的@Component效果一样,主要用于做区分。
@Bean 通常使用在 @Configuration 修饰的配置类中,该注解功能相当于<bean />元素
常用的属性:
a、name:bean id 。name可以省略,省略时bean名称为方法名。也可以指定多个名称(逗号隔开)。
b、autowire: 是否自动注入,默认Autowire.NO
c、initMethod:bean的初始化方法。在依赖注入之后执行<bean id="" init-method="">
d、destroyMethod: spring容器关闭时bean调用的方法 <bean id="" destroty-method="">
当然@Bean还可以配合@Scope指定bean的作用域
@Bean
public User user(){
return new User();
}
2、@ConfigurationProperties
用于从属性文件中获取值 application.properties 或者 application.yml。当然了 如果在配置文件中引入其他配置文件,也可以获取到属性值。
# 开发环境的配置文件 application-dev.properties
# 通常会配置三套, 生产,测试,本地
# 将通用部分配置存放在 application.yml,譬如 数据库连接等信息存放在application-xxx.yml中。这样不用每次都要繁琐的修改。
spring.profiles.active=dev
包含的属性:
a、value | prefix 两者互为别名。指定前缀,默认为""
b、ignoreUnknownFields:默认为true。是否忽略未知字段,当实体中的字段在配置文件中不存在时,是忽略还是抛出异常
c、ignoreInvalidFields: 默认false。 是否忽略不合法的字段,此处的不合法是指类型不合适,配置文件中存在改配置但是无法转化为指定的字段类型。
Mybatis属性配置
application.properties:
# 配置mybatis
mybatis.configuration.mapperLocations=classpath:mybatis/mapper/*.xml
mybatis.configuration.typeAliasPackage=com.example.domain
mybatis.configuration.configLocation=classpath:mybatis/mybatis-config.xml
ConfigurationProperties 可以配置前缀,然后会根据实体的变量名拼接前缀,去配置文件中查询配置。
@Component
@ConfigurationProperties(prefix="mybatis.configuration")
@Data
public class MybatisProperties {
private String configLocation ; //配置文件的路径等价于 @Value("mybatis.configuration.configLocation")
private String mapperLocations; //配置Mapper映射文件的路径
private String typeAliasPackage; //别名的实体路径
}
3、@Configuration
修饰一个Java类,被修饰的类相当于一个xml配置文件。功能类似于 <beans> </beans>。在springboot中大量使用了该注解,该注解提供了一种使用Java类方式配置bean。
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration {
@AliasFor(
annotation = Component.class
)
String value() default "";
}
可以发现 @Configuration使用了@Component 注解修饰。
实例:
配置Mybatis会话工厂
@Configuration
@AutoConfigureAfter(DataSourceConfig.class)
public class MyBatisConfig {
@Autowired
private DataSource dataSource;
@Autowired
MybatisProperties mybatisProperties;
@Bean(name="sqlSessionFactory")
@Primary
public SqlSessionFactory getSqlSessionFactory() throws Exception {
SqlSessionFactoryBean factoryBean=new SqlSessionFactoryBean();
factoryBean.setDataSource(dataSource); //配置数据源
factoryBean.setTypeAliasesPackage(mybatisProperties.getTypeAliasPackage()); //实体类所在包
factoryBean.setConfigLocation(new DefaultResourceLoader().getResource(mybatisProperties.getConfigLocation()));// mapper配置文件
factoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(mybatisProperties.getMapperLocations())); //Mapper实体类所在路径
return factoryBean.getObject();
}
@Bean
public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
return new SqlSessionTemplate(sqlSessionFactory);
}
// 事务管理器
@Bean
public PlatformTransactionManager getDatasourceManager(){
return new DataSourceTransactionManager(dataSource);
}
}
4、@Import
功能和 <import/> 类似,修饰Java类,用于向当前类导入其他配置类。 可以导入多个配置文件,通常用于导入不在包扫描范围内的配置文件。可以被扫描的配置类可以直接访问,没有必要使用@Import 导入。
比如 SpringBoot的启动类指定的包扫描路径为com.example
@SpringBootApplication
@ComponentScan("com.example")
@MapperScan("com.example.mapper")
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
数据库的配置文件在 com包下。
package com;
@Configuration
public class DataSourceConfig {
@Autowired
private JdbcProperties properties;
@Bean(name = "dataSource")
@Primary
public DataSource getSqlDataSource() throws SQLException {
DruidDataSource datasource=new DruidDataSource();
............................
return datasource;
}
}
在MyBatisConfig 中引入 DataSourceConfig, 就会解析DataSourceConfig。将解析出的Bean交给容器管理
@Configuration
@AutoConfigureAfter(DataSourceConfig.class)
@Import(DataSourceConfig.class)
public class MyBatisConfig
5、@ImportResource
修饰Java类,用于向类引入xml配置文件。
用于导入包含bean定义的配置文件,功能和 <import/> 类似。默认情况下可以处理后缀为 .groovy 和.xml 的配置文件
@AliasFor("locations")
String[] value() default {};
@ImportResource({"classpath:config/beans.xml"})
6、@Value("${expression}")
修饰成员变量或者 方法、构造器的参数,用于属性值注入(在配置文件中配置的值)。
注意:@Value不能对static 属性注入。
如果的确需要注入到静态变量,可以通过以下方式间接进行注入:
1)、设置一个私有静态 实例
2)、通过构造函数或者 @PostConstruct 注解为 静态实例 赋值,指向本身(this)
3)、对成员属性注入内容
4)、提供静态方法,使用静态实例获取成员属性
@Component
public class AMSTopicConfig {
private static AMSTopicConfig singleObj;
@Value("${njbp.mam.op.to.etl.entertainer.tag:njbp_mam_op_to_etl_entertainer_tag}")
private String mergePersonTopic;
@PostConstruct
public void init() {
// 为静态属性赋值
AMSTopicConfig.singleObj = this;
}
public static String getMergePersonTopic() {
return singleObj.mergePersonTopic;
}
}
7、@PropertySource(value=“classpath:jdbc.properties”)
该注解用来加载属性文件。
常用属性:
a、ignoreResourceNotFound: 当资源文件找不到的时候是否会忽略该配置,而不是抛出错误。一般用于可选项
b、encoding : 资源文件使用什么编码方式
c、value : 指定属性文件位置。可以配置多个属性文件,不可以使用通配符。
在 PropertySource 中可以指定多个路径,并且会将属性文件中的值加载到 Environment 中。
@ConfigurationProperties 和 @PropertySource
它们的使用有一些差异:
1)、@PropertySource使用该注解加载的是相对独立的属性文件,可以同时加载多个文件(xxx.properties),而且不支持自动注入,不支持前缀注入
2)、@ConfigurationProperties 用于加载配置文件(application.properties | application.yml)。该注解功能更强大:
a、支持前缀注入 (prefix)
b、相同属性名的自动注入
c、$("") 支持EL表达式注入
应用实例:
在以往的开发中通常会将数据库连接信息存放在单独的属性文件中(jdbc.properties)。而在spring boot 中我们会将数据库的信息存放在配置文件中,这会极大便利开发工作。
jdbc.properties:
#数据源配置
spring.datasource.url=xxxxxxxx
spring.datasource.username=xxxx
..............................
可以通过 @Value 注解将配置文件的值注入到实体类中
@Configuration
@PropertySource("classpath:jdbc.properties")
@Data
public class JdbcProperties {
@Value("${spring.datasource.maxActive}")
private String url;
@Value("${spring.datasource.maxActive}")
private String type;
..............................
}
也可以注入Environment ,通过Environment 获取值
@Configuration
@PropertySource("classpath:jdbc.properties")
public class AppConfig {
@Autowired
Environment env;
@Bean
public User user() {
System.out.println(env.getProperty("spring.datasource.url"));
return new User();
}
}
四、SpringMVC相关注解
1、@ResponseBody
控制器方法返回值会使用HttpMessageConverter 进行数据格式化,转化为JSON字符串。
同样的 ResponseBodyAdvice: 针对使用@ResponseBody的注解的类,方法做增强处理。
2、@RestController
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController
@RestController = @Controller + @ResponseBody, 所以通常直接使用@RestController 注解
3、@RequestBody
从Reuqest请求体中获取内容,绑定到方法的指定参数上。 SpringMVC 使用HttpMessageConverter 接口将请求体中的数据转化为方法参数类型。
SpringMVC 给用户对参数的处理提供了很大支配权。 我们可以使用 接口RequestBodyAdvice 来实现对参数进行拦截处理。
注意
1)、RequestBodyAdvice : 针对所有以@RequestBody的参数做处理
2)、自定义的处理对象类上必须得加上@ControllerAdvice注解!
利用此功能我们可以做以下处理工作:
1)、参数做解密处理。
2)、修改接受的参数数据。
4、@RequestParam
从Request请求中获取指定的参数。
可以设置的属性:
1)、required : 默认为true 参数必须存在。参数不存在时抛出异常(
MissingServletRequestParameterException). 提示信息
2)、defaultValue : 设置参数默认值。 当参数没有提供或者为空值时生效, 包含隐式定义required=false
3)、name | value , 互为别名的属性, 绑定请求中的参数名。 request.getParameter(name);
5、@RequestMapping
用于设置 请求 和 Method 的映射关系。指明何种请求可以和方法匹配
可配置属性值:
1)、path、value、 name, 互为别名,设置可以处理的url。
2)、consumes,字符串数组。 指定可以处理的 媒资类型,仅当请求头中的 Content-Type 与其中一种媒体类型匹配时,才会映射请求。所以该配置会缩小可匹配的请求。当url 匹配但是consumes不匹配时, 状态码415。不设置的话,表示不限制媒资类型,参数的具体使用何种方式解析,SpringMVC会选择合适的处理器处理。
3)、produces,字符串数组。 生成的媒资类型,该属性会影响实际的输出类型。和consumes一样,改配置会缩小匹配的范围。 只有当请求头中的 Accept 与 配置的任意一个媒资类型匹配时,才会映射请求。当url 匹配与consumes不匹配时, 状态码406 。比如:为了生成UTF-8编码的JSON响应,应使用
MediaType.APPLICATION_JSON_UTF8_VALUE。
相关推荐
-
- SpringBoot如何实现优雅的参数校验
-
平常业务中肯定少不了校验,如果我们把大量的校验代码夹杂到业务中,肯定是不优雅的,对于一些简单的校验,我们可以使用java为我们提供的api进行处理,同时对于一些...
-
2025-05-11 19:46 ztj100
- Java中的空指针怎么处理?
-
#暑期创作大赛#Java程序员工作中遇到最多的错误就是空指针异常,无论你多么细心,一不留神就从代码的某个地方冒出NullPointerException,令人头疼。...
- 一坨一坨 if/else 参数校验,被 SpringBoot 参数校验组件整干净了
-
来源:https://mp.weixin.qq.com/s/ZVOiT-_C3f-g7aj3760Q-g...
- 用了这两款插件,同事再也不说我代码写的烂了
-
同事:你的代码写的不行啊,不够规范啊。我:我写的代码怎么可能不规范,不要胡说。于是同事打开我的IDEA,安装了一个插件,然后执行了一下,规范不规范,看报告吧。这可怎么是好,这玩意竟然给我挑出来这么...
- SpringBoot中6种拦截器使用场景
-
SpringBoot中6种拦截器使用场景,下面是思维导图详细总结一、拦截器基础...
- 用注解进行参数校验,spring validation介绍、使用、实现原理分析
-
springvalidation是什么在平时的需求开发中,经常会有参数校验的需求,比如一个接收用户注册请求的接口,要校验用户传入的用户名不能为空、用户名长度不超过20个字符、传入的手机号是合法的手机...
- 快速上手:SpringBoot自定义请求参数校验
-
作者:UncleChen来源:http://unclechen.github.io/最近在工作中遇到写一些API,这些API的请求参数非常多,嵌套也非常复杂,如果参数的校验代码全部都手动去实现,写起来...
- 分布式微服务架构组件
-
1、服务发现-Nacos服务发现、配置管理、服务治理及管理,同类产品还有ZooKeeper、Eureka、Consulhttps://nacos.io/zh-cn/docs/what-is-nacos...
- 优雅的参数校验,告别冗余if-else
-
一、参数校验简介...
- Spring Boot断言深度指南:用断言机制为代码构筑健壮防线
-
在SpringBoot开发中,断言(Assert)如同代码的"体检医生",能在上线前精准捕捉业务逻辑漏洞。本文将结合企业级实践,解析如何通过断言机制实现代码自检、异常预警与性能优化三...
- 如何在项目中优雅的校验参数
-
本文看点前言验证数据是贯穿所有应用程序层(从表示层到持久层)的常见任务。通常在每一层实现相同的验证逻辑,这既费时又容易出错。为了避免重复这些验证,开发人员经常将验证逻辑直接捆绑到域模型中,将域类与验证...
- SpingBoot项目使用@Validated和@Valid参数校验
-
一、什么是参数校验?我们在后端开发中,经常遇到的一个问题就是入参校验。简单来说就是对一个方法入参的参数进行校验,看是否符合我们的要求。比如入参要求是一个金额,你前端没做限制,用户随便过来一个负数,或者...
- 28个验证注解,通过业务案例让你精通Java数据校验(收藏篇)
-
在现代软件开发中,数据验证是确保应用程序健壮性和可靠性的关键环节。JavaBeanValidation(JSR380)作为一个功能强大的规范,为我们提供了一套全面的注解工具集,这些注解能够帮...
- Springboot @NotBlank参数校验失效汇总
-
有时候明明一个微服务里的@Validated和@NotBlank用的好好的,但就是另一个里不能用,这时候问题是最不好排查的,下面列举了各种失效情况的汇总,供各位参考:1、版本问题springbo...
- 这可能是最全面的Spring面试八股文了
-
Spring是什么?Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- idea eval reset (50)
- vue dispatch (70)
- update canceled (42)
- order by asc (53)
- spring gateway (67)
- 简单代码编程 贪吃蛇 (40)
- transforms.resize (33)
- redisson trylock (35)
- 卸载node (35)
- np.reshape (33)
- torch.arange (34)
- node卸载 (33)
- npm 源 (35)
- vue3 deep (35)
- win10 ssh (35)
- exceptionininitializererror (33)
- vue foreach (34)
- idea设置编码为utf8 (35)
- vue 数组添加元素 (34)
- std find (34)
- tablefield注解用途 (35)
- python str转json (34)
- java websocket客户端 (34)
- tensor.view (34)
- java jackson (34)