Spring-注解编程

注解基础概念

1.什么是注解编程

指的是在类或者方法上加入特定的注解(@XXX) 完成特定功能的开发

@Component

public classXXX{}

 2.为什么要讲注解编程

1.注解开发方便

        代码简洁 开发速度大大提高

2.Spring开发潮流

    Spring2.x引入注解 Spring3.x完善注解 Springboot普及 推广注解编程

3.注解的作用

  • 替换XML这种配置形式,简化配置

  • 替换接口,实现调用双方的契约性

通过注解的方式,在功能调用者和功能提供者之间达成约定,进而进行功能的调用。因为注解应用更为方便灵活

4.Spring注解的发展历程

1.Spring2.x开始支持注解编程 @Componet @Service @Scope

        目的:提供这些注解只是为了在某些情况下简化XML的配置,作为XML开发的有益补充

2.Spring3.x @Configuration @Bean..

        目的:彻底替换XML,基于纯注解编程

3.Spring 4.x Springboot

       提倡使用注解常见开发

5.Spring注解开发的一个问题

Spring基于注解进行配置后,还能否解耦合呢?

Spring框架应用注解时,如果对注解配置的内容不满意,可以通过Spring配置文件进行覆盖

Spring基础注解(Spring2.x)

这个阶段注解 仅仅是简化XML配置 并不能完全替代XML

搭建开发环境

<context:compoent-scan base-package=""/>

作用:让Spring框架在设置包及其子包中扫描对应的注解 使其生效

 对象创建相关注解

@Component

作用:替换原有Spring配置文件中的<bean>标签

注意:

        id属性 component注解 提供了默认的设置方式 首单词首字母小写

        class属性 通过反射获得class内容

@Component细节
  • 如何显示指定工厂创建对象的id值

@Component("u")

  • Spring配置文件覆盖注解配置内容

applicationContext.xml

@Repository ---->XXXDAO

         @Repository

          public class UserDao{

}

@Service

        @Service

        public class UserService{

}

@Controller

        @Controller

        public class RegAction{

}

<bean id="和注解一致" class=""/>

id值  class的值 要和 注解中的设置保持一致

@Repository

@Service

@Controller

注解:本质上这些衍生注解就是@Component 

        作用<bean

        细节 @Service("s")

目的:更加准确的表达这一个类型的作用


注意:Spring整合Mybatis开发过程中 不使用@Repository @Component Dao的实现Spring创建了
 

  • @Scope注解

作用:控制简单对象创建次数
<bean id="" class="" scope="singleton/prototype"/>

 @Lazy注解

作用:延迟创建单例对象

一旦使用@Lazy注解后,Spring会在使用这个对象的时候,进行这个对象的创建

 注入相关注解

@Autowired

@Autowired细节分析

1.Autowired注解基于类型注入

        基于类型的注入:注入对象的类型,必须与目标成员变量类型想通过或者其子类(实现类)

2.Autowired Qualifier 基于名字进行注入(了解)

        基于名字的注入:注入对象的id值,必须与Qualifier注解中设置的名字相同

3.Autowired注解放置位置

        a)放置在对应成员变量的set方法上

        b)直接把这个注解放置在成员变量上,Spring通过反射直接对成员变量进行注入(赋值)推荐


4.javaEE规范中类似功能的注解

        JSR250 @Resource(name="userDAOImpl") 基于名字进行注入

        @Autowired()

        @Qualifier("userDAOImpl")

        注意:如果在应用Resource注解时,名字没有配对成功 那么会继续按照类型进行注入

        
 

 @Value注解

@Valye注解

1.设置 xxx.properties

        id=10

        name=gao

2.Spring工厂 读取这个配置文件

        <context:property-placeholder location=""/>

3.代码

        属性 @Value("${key}")

 @PropertySource

替换Spring配置文件中的<context:property-placeholder>标签

 @Value注解细节
  • @Value注解不能应用在静态成员变量上
  • @Value注解-properties 不能注入集合类型

注解扫描详解

<context:component-scan base-package="">

        <context:exclude-fliter type="" expression=""/>

       

</context component-scan>

当前包 及其子包


type:assignable 排除特定类型 不进行创建

type="annotation" 排除带@Service注解类型

type="aspectj" 切入点表达式 只能应用包切入点 类切入点

type ="regex" 正则表达式

type ="custom" 自定义排除策略

第三种常用
---可以多个叠加

 包含方式

基于注解开发的思考

配置互通

Spring注解配置 配置文件配置 互通

ref引用就是UserDaoImpl首字母小写创建的对象

 什么情况下使用注解 什么情况下使用配置文件

@Component 替换<bean

基础注解(@Componet @Autowired @Value) 程序员开发类型配置

1.程序员开发的类型上  可以加入对应注解 进行对象的创建
User UserService UserDao...

2应用其它非程序员开发的类型时,还是需要<bean 进行配置的

SqlSessionFactoryBean MapperScannerConfigrue

 Spring的高级注解(Spring3.x及以上)

1.配置Bean

Spring在3.x提供新的注解 用于替换XML配置文件

@Configuration

public class AppConfig{

}

 1.配置Bean 替换了XML的什么内容?

 2.AnnotationConfigApplicationContext

1.创建工厂代码

ApplicationContext ctx=new AnnotationConfigApplicationContext

2.指定配置文件

        1.指定配置bean的Class

        ApplicationContext ctx=new AnnotationConfigAplicationContext(AppConfig.class)

        2,指定配置bean所在的路径

        ApplicationContext ctx=new AnnotationConfigAplicationContext("包名");

 配置Bean开发的细节分析

引入配置文件log.propertities

@Configuration的本质

@Component的衍生注解


可以应用<context:component-scan 进行扫描

 2.@Bean注解

@Bean注解在配置bean中进行使用,等同于XML配置文件中的<bean>标签

 1.@Bean注解的基本使用

对象的创建     

1.简单对象

        直接通过new方式创建的对象

 User UserService UserDao

2.复杂对象

        不能通过new的方式直接创建的对象

        Connection SqlSessionFactory

public class AppConfig {@Beanpublic User user(){return new User();}/*创建一个复杂对象*/@Beanpublic Connection connection() throws ClassNotFoundException, SQLException {Class.forName("com.mysql.jdbc.Driver");Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/sky_take_out?useSSL=false","root","123456");return connection;}
}
@Bean注解自定义id值
 @Bean("u")public User user(){return new User();}/*
@Bean控制对象的创建次数
@Bean("u")@Scope("singleton")public User user(){return new User();}
@Bean用户自定义类型注入
package annotationHigh;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class AppConfig1 {@Beanpublic User user(){return new User();}@Beanpublic UserDao userDao(){return new UserDaoImpl();}@Beanpublic UserService userService(UserDao userDao){UserServiceImpl userService = new UserServiceImpl();userService.setUserDao(userDao);return userService;}
//    @Bean
//    public UserService userService(){
//        UserServiceImpl userService = new UserServiceImpl();
//        userService.setUserDao(userDao());
//        return userService;
//    }
}
@Bean(JDK类型注入)

@BeanJDK类型注入细节分析 

如果直接在代码中进行set方法的调用 会存在耦合问题

package annotationHigh;import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;@Configuration
@PropertySource(value = "classpath:init.properties")
public class AppConfig1 {@Value("${id}")private Integer id;@Value("${name}")private String name;@Beanpublic User user(){return new User();}@Beanpublic UserDao userDao(){return new UserDaoImpl();}@Beanpublic UserService userService(UserDao userDao){UserServiceImpl userService = new UserServiceImpl();userService.setUserDao(userDao);return userService;}
//    @Bean
//    public UserService userService(){
//        UserServiceImpl userService = new UserServiceImpl();
//        userService.setUserDao(userDao());
//        return userService;
//    }@Beanpublic Customer customer(){Customer customer = new Customer();customer.setId(id);customer.setName(name);return customer;}
}

@ComponentScan注解

@ComponentScan注解在配置bean中进行使用,等同于XML配置文件中的<context:component-scan>标签


目的:进行相关注解的扫描:(@Component @Value ...@Autowired)

 基本使用

@Configuration
@ComponentScan(basePackages ="annontation")
public class AppConfig2 {
}
 排除、包含的使用

包含

Spring创建工厂的多种方式 

1.多种配置的应用场景

 2。配置优先级

@Component及其衍生注解<@Bean <配置文件bean标签

优先级高的配置 覆盖优先级低的配置
@Component

public class User{

}

@Bean

public User user(){

        return new User();

}

<bean id="user"class=""/>

注意:id值 应该保持一致

3.解决基于注解进行配置的耦合问题

@Configuration

//@ImportResources("applicationContext.xml")--------也会耦合

public class AppConfig4{

        @Bean

        public UserDao userDao(){

                return new UserDaoImpl();

        }

}


applicationContext.xml

<bean id="userDao" class=""/>

4.整合多个配置信息

为什么会有多个配置信息

拆分多个配置bean的开发,是一种模块化开发的形式,也体现了面向对象各司其职的设计思想

 5.多配置信息整合的方式

1.多个配置Bean的整合

2.配置Bean与@Component相关注解的整合

3.配置Bean与SpringXML配置文件的整合

整合洞中配置信息需要关注哪些要点

1.如何使多种配置信息 汇成一个整体

2.如何实现跨配置的注入

1.多个配置Bean的整合

base-package进行多个配置Bean的整合

 @Import

1.可以创建对象

2.多种配置bean的整合

 2.跨配置进行注入

在应用配置Bean的过程中,不管使用哪种方式进行配置信息的汇总,其操作方式都是通过成员变量加入@Autowired注解进行完成

 配置Bean与@Component相关注解的整合

 配置Bean与配置文件的整合

1.遗留系统的整合 2.配置覆盖

 配置Bean的底层实现原理

四维一体的开发思想 

1.什么是四维一体

Spring开发一个功能的4种形式,虽然开发方式不同,但最终效果是一样的

1.基于schema

2.基于特定功能注解

3.基于原始<bean

4.基于@Bean注解

2.四维一体的开发案例

1. <context:property-placeholder

<?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.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><context:property-placeholder location="classpath:init.properties"/><bean id="category" class="annontation.Category"></bean><context:component-scan base-package="annontation"></context:component-scan>
</beans>
package annontation;import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;//@Component
//@PropertySource(value = "classpath:init.properties")
public class Category {@Value("${id}")private Integer id;@Value("${name}")private String name;public Category() {}public Category(Integer id, String name) {this.id = id;this.name = name;}/*** 获取* @return id*/public Integer getId() {return id;}/*** 设置* @param id*/public void setId(Integer id) {this.id = id;}/*** 获取* @return name*/public String getName() {return name;}/*** 设置* @param name*/public void setName(String name) {this.name = name;}public String toString() {return "Categpry{id = " + id + ", name = " + name + "}";}
}

@PropertySource [推荐]

<?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.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><!--    <context:property-placeholder location="classpath:init.properties"/>-->
<!--    <bean id="category" class="annontation.Category"></bean>--><context:component-scan base-package="annontation"></context:component-scan>
</beans>
package annontation;import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;@Component
@PropertySource(value = "classpath:init.properties")
public class Category {@Value("${id}")private Integer id;@Value("${name}")private String name;public Category() {}public Category(Integer id, String name) {this.id = id;this.name = name;}/*** 获取* @return id*/public Integer getId() {return id;}/*** 设置* @param id*/public void setId(Integer id) {this.id = id;}/*** 获取* @return name*/public String getName() {return name;}/*** 设置* @param name*/public void setName(String name) {this.name = name;}public String toString() {return "Categpry{id = " + id + ", name = " + name + "}";}
}

<bean id="" class="PropertySourcePlaceholderCoonfigure"/>

<?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.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><bean id="category" class="annontation.Category"></bean><bean id="propertyholder" class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer"><property name="location" value="classpath:init.properties"></property></bean><context:component-scan base-package="annontation"></context:component-scan>
</beans>

@Bean  [推荐]
 

package annontation;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.core.io.ClassPathResource;@Configuration
@ComponentScan(basePackages = "annontation")
public class AppConfig6 {@Beanpublic PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer();propertySourcesPlaceholderConfigurer.setLocations(new ClassPathResource("init.properties"));return propertySourcesPlaceholderConfigurer;}
}

纯注解AOP开发
package annontation;import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;@Configuration
@ComponentScan(basePackages = "annontation")
@EnableAspectJAutoProxy
public class AppConfig7 {
}
package annontation;import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;@Aspect
@Component
public class MyAspect {//切入点@Pointcut("execution(* *(..))")public void myPointcut(){};//切面@Around(value="myPointcut()")public Object around(ProceedingJoinPoint joinPoint) throws Throwable{System.out.println("before");Object ret=joinPoint.proceed();System.out.println("after");return ret;}
}

 细节分析

代理创建方式切换JDK Cglib

@EnableAspectjAutoProxy

切换为cglib

@EnableAspectJAutoProxy(proxyTargetClass = True)
纯注解版Spring+MyBatis整合

1.连接池

<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"><property name="url" value="jdbc:mysql://localhost:3306/db03?useSSL=false"/><property name="username" value="root"/><property name="password" value="123456"/><property name="driverClassName" value="com.mysql.jdbc.Driver"/>
</bean>

@Bean

public DruidDataSource dataSource(){

        DruidDataSource dataSource=new DruidDataSource();

        dataSource.setDriverClassName("");

        dataSource.setUrl();

        return dataSource;

}
2.SqlSessionFactoryBean

<!--    创建sqlSessionFactory SqlSessionFactoryBean--><bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><property name="dataSource" ref="dataSource"/><property name="mapperLocations"><list><value>classpath:mybatis.mapper/*Mapper.xml</value></list></property></bean>
@Bean
public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource){SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();sqlSessionFactoryBean.setDataSource(dataSource);sqlSessionFactoryBean.setMapperLocations(new ClassPathResource("mybatis.mapper/EmpMapper.xml"));return sqlSessionFactoryBean;
}

 编码

1.实体

2.表

3.Dao接口

4.Mapper文件

1. MapperLocations编码时通配写法

//设置Mapper文件路径

ResourcePatternResolver resolver=new PathMatchingResourcePatternResolver();
Resource[]resources=resolver.getResources("mybatis.mapper/*Mapper.xml");
sqlSessionFactoryBean.setMapperLocations(resources);
 2.配置Bean数据耦合的问题

package mybatis;import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;@Component
@PropertySource("classpath:mybatis.properties")
public class MybatisProperties {@Value("${mybatis.driverClassName}")private String driverClassName;@Value("${mybatis.url}")private String url;@Value("${mybatis.username}")private String username;@Value("${mybatis.password}")private String password;@Value("${mybatis.mapperLocations}")private String mapperLocations;public MybatisProperties() {}public MybatisProperties(String driverClassName, String url, String username, String password, String mapperLocations) {this.driverClassName = driverClassName;this.url = url;this.username = username;this.password = password;this.mapperLocations = mapperLocations;}/*** 获取* @return driverClassName*/public String getDriverClassName() {return driverClassName;}/*** 设置* @param driverClassName*/public void setDriverClassName(String driverClassName) {this.driverClassName = driverClassName;}/*** 获取* @return url*/public String getUrl() {return url;}/*** 设置* @param url*/public void setUrl(String url) {this.url = url;}/*** 获取* @return username*/public String getUsername() {return username;}/*** 设置* @param username*/public void setUsername(String username) {this.username = username;}/*** 获取* @return password*/public String getPassword() {return password;}/*** 设置* @param password*/public void setPassword(String password) {this.password = password;}/*** 获取* @return mapperLocations*/public String getMapperLocations() {return mapperLocations;}/*** 设置* @param mapperLocations*/public void setMapperLocations(String mapperLocations) {this.mapperLocations = mapperLocations;}public String toString() {return "MybatisProperties{driverClassName = " + driverClassName + ", url = " + url + ", username = " + username + ", password = " + password + ", mapperLocations = " + mapperLocations + "}";}
}
package mybatis;import com.alibaba.druid.pool.DruidDataSource;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;import javax.sql.DataSource;
import java.io.IOException;@Configuration
@ComponentScan("mybatis")
@MapperScan(basePackages = "mybatis")
public class MyBatisAutoConfiguration {@Autowiredprivate MybatisProperties mybatisProperties;@Beanpublic DataSource dataSource(){DruidDataSource dataSource = new DruidDataSource();dataSource.setDriverClassName(mybatisProperties.getDriverClassName());dataSource.setUrl(mybatisProperties.getUrl());dataSource.setPassword(mybatisProperties.getPassword());dataSource.setUsername(mybatisProperties.getUsername());return dataSource;}@Beanpublic SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource) throws IOException {SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();sqlSessionFactoryBean.setDataSource(dataSource);ResourcePatternResolver resolver=new PathMatchingResourcePatternResolver();Resource[]resources=resolver.getResources(mybatisProperties.getMapperLocations());sqlSessionFactoryBean.setMapperLocations(resources);return sqlSessionFactoryBean;}}

纯注解版本事务编程 

1.原始对象 XXX

<bean id="userService" class="xxx">

        <property name="userDao" ref="userDao">

@Service

public class UserServiceImpl implements UserService{

        @Autowired

        private UserDao userDao;

}

2.额外功能

<!----DataSourceTransactionManager>

        <bean id="dataSourceTransactionManager" class="org.spring.framework.jdbc.dataSource.DataSourceTransactionManager">

        <property name="dataSource" ref="dataSource">

</bean>
 

@Bean
public DataSourceTransactionManager dataSourceTransactionManager(){DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();dataSourceTransactionManager.setDataSource(dataSource);return dataSourceTransactionManager;
}

3.事务属性

        

@Transactional()
@Service
public class EmpServiceImpl implements EmpService{@Autowiredprivate EmpDao empDao;@Overridepublic void register(Emp emp) {empDao.add(emp);}
}

4.基于Schema的事务配置

<tx:annotation-driven transaction-manage="dataSourceTransactionManage"/>

@EnableTransactionManger--配置Bean

package mybatis;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;import javax.sql.DataSource;//Mybatis已经配置过扫描了
@Configuration
@EnableTransactionManagement
public class TransactionAutoConfiguration {//跨配置注入@Autowiredprivate DataSource dataSource;@Beanpublic DataSourceTransactionManager dataSourceTransactionManager(){DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();dataSourceTransactionManager.setDataSource(dataSource);return dataSourceTransactionManager;}
}

 Spring与YAML文件整合

1.什么是YML

YAML是一种新形式的配置文件,比XML更简单,比Properties更强大

 2.Properties进行配置问题

1.Properties表达过于繁琐,无法表达数据的内在联系

2.Properties无法表达对象 集合类型

3.YAML语法简洁

 1.定义yml文件

xxx.yml xxx.yaml

2.语法

  1.基本语法

        key:空格value

        name: suns

        password:123456

   2.对象概念

        account:

                id:1

                password:123456

    3.定义集合

        service

                -1111

                -2222

 4.Spring与YML集成思路分析

1.准备yml配置文件

        init.yml

        name: suns

        password: 123456

2.读取yml 转换成 Properties

        YamlPropertiesFactoryBean.setResources(yml配置文件路径) new ClassPathResources();

        YamlPropertiesFactoryBean.getObject()---->Properties

 3.应用PropertSourcePlaceholderConfigurer

        PropertySourcePlaceholderConfigurer.setProperties();

4.类中@Value注解注入

 5.Spring与YML集成编码

环境搭建

<dependency><groupId>org.yaml</groupId><artifactId>snakeyaml</artifactId><version>1.29</version>
</dependency>
最低版本1.18

编码 

1.准备yml配置文件

2.配置Bean中操作 完成YAML读取 与PropertySourcePlaceholderConfigure的创建

3.类 加入@Value注解

account:name: gaopassword: 123456
package yml;import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.core.io.ClassPathResource;import java.util.Properties;@Configuration
@ComponentScan(basePackages = "yml")
public class YmlAutoConfiguration {@Beanpublic PropertySourcesPlaceholderConfigurer propertySourcePlaceholderConfigurer() {YamlPropertiesFactoryBean yamlPropertiesFactoryBean = new YamlPropertiesFactoryBean();yamlPropertiesFactoryBean.setResources(new ClassPathResource("init.yml"));Properties properties = yamlPropertiesFactoryBean.getObject();PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();configurer.setProperties(properties);return configurer;}
}

 集成问题

1.集合处理问题

SpringEL表达式解决

@Value("#{'${list}'/split(',')}")

2.对象类型的YAML进行配置时 过于繁琐
@Value("${account.name}")

SpringBoot @ConfigurationProperties

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/75773.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Dify智能体平台源码二次开发笔记(5) - 多租户的SAAS版实现(2)

目录 前言 用户的查询 controller层 添加路由 service层 用户的添加 controller层 添加路由 service层-添加用户 service层-添加用户和租户关系 验证结果 结果 前言 完成租户添加功能后&#xff0c;下一步需要实现租户下的用户管理。基础功能包括&#xff1a;查询租…

基于若依的ruoyi-vue-plus的nbmade-boot在线表单的设计(一)架构方面的设计

希望大家一起能参与我的新开源项目nbmade-boot: 宁波智能制造低代码实训平台 主要目标是类似设计jeecgboot那样的online表单功能,因为online本身没有开源这部分代码,而我设计这个是完全开源的,所以希望大家支持支持,开源不容易。 1、数据库方面设计考虑 是在原来gen_table和…

WebFlux应用中获取x-www-form-urlencoded数据的六种方法

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;精通Java编…

[Python基础速成]1-Python规范与核心语法

本系列旨在快速掌握Python&#xff0c;实现能够快速阅读和理解 Python 代码&#xff0c;并在可查阅语法的情况下进行 AI 学习。 本篇先了解一下Python基础知识。 本篇内容较菜鸟教程有所删减、方便快速构建大纲&#xff0c;且加入了PEP 8规范说明等有助于理解和编写代码的说明。…

农民剧团的春天与改变之路

杨天义&#xff0c;男&#xff0c;1966年9月生&#xff0c;中共党员&#xff0c;江西省吉安市吉水县水南农民剧团团长。 杨天义从废品收购起家&#xff0c;凭借自身的努力和奋斗&#xff0c;自筹资金100余万元建设了水南镇的第一座影剧院&#xff0c;组建了江西省吉安市吉水县…

python asyncio 的基本使用

1、引言 asyncio 是 Python 标准库中的一个库&#xff0c;提供了对异步 I/O 、事件循环、协程和任务等异步编程模型的支持。 asyncio 文档 2、进程、线程、协程 线程 线程是操作系统调度的基本单位&#xff0c;同一个进程中的多个线程共享相同的内存空间。线程之间的切换由操…

Leedcode刷题 | Day30_贪心算法04

一、学习任务 452. 用最少数量的箭引爆气球代码随想录435. 无重叠区间763. 划分字母区间 二、具体题目 1.452用最少数量的箭引爆气球452. 用最少数量的箭引爆气球 - 力扣&#xff08;LeetCode&#xff09; 在二维空间中有许多球形的气球。对于每个气球&#xff0c;提供的输…

Ant Design Vue 表格复杂数据合并单元格

Ant Design Vue 表格复杂数据合并单元格 官方合并效果 官方示例 表头只支持列合并&#xff0c;使用 column 里的 colSpan 进行设置。 表格支持行/列合并&#xff0c;使用 render 里的单元格属性 colSpan 或者 rowSpan 设值为 0 时&#xff0c;设置的表格不会渲染。 <temp…

C++ 标准库中的 <algorithm> 头文件算法总结

C 常用 <algorithm> 算法概览 C 标准库中的 <algorithm> 头文件提供了大量有用的算法&#xff0c;主要用于操作容器&#xff08;如 vector, list, array 等&#xff09;。这些算法通常通过迭代器来操作容器元素。 1. 非修改序列操作 std::all_of, std::any_of, s…

程序化广告行业(84/89):4A广告代理公司与行业资质解读

程序化广告行业&#xff08;84/89&#xff09;&#xff1a;4A广告代理公司与行业资质解读 大家好&#xff01;在探索程序化广告行业的道路上&#xff0c;每一次知识的分享都是我们共同进步的阶梯。一直以来&#xff0c;我都希望能和大家携手前行&#xff0c;深入了解这个充满机…

deepin使用autokey添加微信快捷键一键显隐ctrl+alt+w

打开deepin商店&#xff0c;搜索快捷键&#xff0c;找到autokey 快捷键管理&#xff0c;点击安装 点击右键新建文件夹 点击右键新建脚本 打开脚本并添加以下内容 import subprocess import time# ------------------ 配置项 ------------------ WM_CLASS "wechat…

文件内容课堂总结

Spark SQL是Spark用于结构化数据处理的模块&#xff0c;前身是Shark。Shark基于Hive开发&#xff0c;虽提升了SQL-on-Hadoop效率&#xff0c;但对Hive依赖过多。2014年6月1日Shark项目停止开发&#xff0c;团队将资源投入Spark SQL项目。Spark SQL具有诸多优点&#xff0c;如摆…

Zotero PDF Translate 翻译插件使用OpenAI API配置教程

PDF Translate&#xff1a;提升 Zotero 内置 PDF 阅读器的翻译功能 “PDF Translate” 是一款为 Zotero 设计的插件&#xff0c;旨在方便用户在 Zotero 内置的 PDF 阅读器中进行划词或段落翻译&#xff0c;辅助阅读外文文献。 一、 安装插件 下载插件&#xff1a; 访问 PDF T…

火山引擎旗下的产品

用户问的是火山引擎旗下的产品&#xff0c;我需要详细列出各个类别下的产品。首先&#xff0c;我得确认火山引擎有哪些主要业务领域&#xff0c;比如云计算、大数据、人工智能这些。然后&#xff0c;每个领域下具体有哪些产品呢&#xff1f;比如云计算方面可能有云服务器、容器…

C/C++程序中实现Python绑定多种技术路线

在C/C程序中实现Python绑定有多种技术路线&#xff0c;选择合适的方法取决于项目需求、性能要求和开发效率。以下是常见的几种方案&#xff0c;按易用性排序&#xff1a; 1. PyBind11&#xff08;推荐首选&#xff09; 特点&#xff1a;现代C库&#xff0c;语法简洁&#xff0…

【位运算】消失的两个数字

文章目录 面试题 17.19. 消失的两个数字解题思路 面试题 17.19. 消失的两个数字 面试题 17.19. 消失的两个数字 ​ 给定一个数组&#xff0c;包含从 1 到 N 所有的整数&#xff0c;但其中缺了两个数字。你能在 O(N) 时间内只用 O(1) 的空间找到它们吗&#xff1f; ​ 以任意…

自然语言处理Hugging Face Transformers

Hugging Face Transformers 是一个基于 PyTorch 和 TensorFlow 的开源库&#xff0c;专注于 最先进的自然语言处理&#xff08;NLP&#xff09;模型&#xff0c;如 BERT、GPT、RoBERTa、T5 等。它提供了 预训练模型、微调工具和推理 API&#xff0c;广泛应用于文本分类、机器翻…

vue开发基础流程 (后20)

创建项目命令&#xff1b; 或者 vue create my - vue - router - project这个是创建带路由的项目 22.组件组成 比如说一个页面吧&#xff0c;他三个组件&#xff0c;template就是用来放所有的标签&#xff0c;script用来放业务逻辑&#xff0c;style用来放样式&#xff0c;c…

高性能内存kv数据库Redis

引言 在当今数据驱动的时代&#xff0c;高效的数据存储和检索对于各类应用程序至关重要。Redis&#xff08;Remote Dictionary Server&#xff09;作为一款开源的内存键值数据库&#xff0c;凭借其出色的性能、丰富的数据结构和灵活的特性&#xff0c;在众多场景中得到了广泛应…

自动化测试概念篇

文章目录 目录1. 自动化1.1 自动化概念1.1.1 回归测试 1.2 自动化分类1.3 自动化测试金字塔 2. web自动化测试2.1 驱动2.1.1 安装驱动管理2.1.2 selenium库 3. Selenium3.1 一个简单的web自动化示例3.2 selenium驱动浏览器的工作原理 目录 自动化web自动化测试Selenium 1. 自…