栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Spring学习

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Spring学习

Spring核心 组件扫描 component scanning

@ComponentScan注解是一个Spring的注解,用于扫描包上的注解将组件加载到IOC容器中。

作用:扫描被@Controller、@Service、@Repository、@Component等注解标注的类。

@ComponentScan注解只能使用在有@Configuration配置注解的地方,因为component-scan标签必须存在于xml配置文件中;而在脱离xml使用时,需要使用带有在@Configuration配置注解上。

简而言之

@Configuration = xml 文件

@ComponentScan用来代替xml文件中的配置control、Service、Repository、Component的配置语句


例如以上语句就扫描了entity包下的所有类,用@ComponentScan代替就是

@Configuration
@ComponentScan(basePackages = {"com.thg.entity"})
public class Config {

}
Component注解

把普通pojo实例化到spring容器中,相当于配置文件中的


使用方法:

  • 在pojo类上加入@Component关键字
  • 如果使用@Configuration配置,则加入@ComponentScan(basePackages = {“com.thg.entity”})扫描包
  • 如果使用xml配置,则加入
Autowire注解

如果说Component=

那么Autowire=

一般@Autowire配合@Component一起使用

  • @Component注册bean
  • @Autowire注入依赖

Autowire有三种注入方式

  • 属性注入
  • setter注入
  • 构造器注入
Qualifier 注解

@Qualifier一般与@Autowire一起用,当我们需要注入的对象有多个时,为了避免歧义装配错了,采用@Qualifier指明需要装配的bean id/name

public class Profile {
   @Autowired
   @Qualifier("student1")
   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() );
   }
}
Bean注解

Bean注解和Component有些类似

Component的作用是标明该类需要被注入,然后使用ComponentScan扫描注入

而Bean注解也是注入,但是他是放在Config类中,去处理某些无法由Component处理的注入的情形

  • 内部类,无法Component
  • Component一个类对应一个bean,如果一个类需要多个Component的时候,使用@bean

比如我需要注入一个Map,显然我不可能跑源码里去注入Map

如果去写xml又显得头重脚轻多此一举,这时bean就起到作用了

@Configuration
@ComponentScan(basePackages = {"com.thg.entity"})
public class Config {

 @Bean
 public Map getMap(){
     Map map = new HashMap<>();
     map.put("no1","thg");
     map.put("no2","thh");
     System.out.println("map is 注入");
     return map;
 }
}
取别名

如上,@bean会将getMap注入到ioc容器中,如果你想换个名字,这样就行了

@Bean(name = "map")
创建函数及销毁函数
 @Bean(initMethod = "init", destroyMethod = "cleanup" )
Config配置

我们使用@Configuration去代替xml文件

@ComponentScan
  • 作用:用来扫描control、Service、Repository、Component的配置语句
  • 等价于
  • 代码位置:放在Config类上
@Import
  • 作用:@import 注解允许从另一个配置类中加载 @Bean 定义。

  • 代码位置:放在Config类上

@Profile

指定组件在哪个环境的情况下才能被注册到容器中,不指定,任何环境下都能注册这个组件

就比如数据库连接池这些,在不同环境下加载不同的属性

需要在主函数拿到context之后指定即可

applicationContext.getEnvironment().setActiveProfiles("dev","master");
Spring Boot SpringBootApplication核心注解

源码如下

package org.springframework.boot.autoconfigure;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
  @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
  @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
   ......
}

package org.springframework.boot;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {

}

简而言之,SpringBootApplication注解等效于下面三个注解的合集

  • @EnableAutoConfiguration:启用 SpringBoot 的自动配置机制
  • @ComponentScan: 扫描被@Component (@Service,@Controller)注解的 bean,注解默认会扫描该类所在的包下所有的类。
  • @Configuration:允许在 Spring 上下文中注册额外的 bean 或导入其他配置类

后两个注解都很熟悉,我们来康康@EnableAutoConfiguration

@EnableAutoConfiguration

默认会扫描与项目启动类同级或者更低级目录下的所有使用@Configuration注解的类

意思就是@Configuration最好放在同级别下,否则你要加入@Improt把你写的config加入进来

config实现的三种方式
  • 直接在SpringBootApplication上加入你需要的东西,因为SpringBootApplication本质就是一个config类
  • 在SpringBootApplication的统计目录或者下级目录下实现一个config类,并用@Configuration标注
  • 在别的地方配置Config 然后使用@Import加入SpringBootApplication
Application配置文件

springboot引入了application.properties和application.yaml来简化配置过程

spring:
  application:
    name: "thg"
  datasource:
    url: jdbc:mysql://sh-cynosdbmysql-grp-bbhdi89q.sql.tencentcdb.com:21590/pic?serverTimezone=UTC
    driver-class-name: com.mysql.jdbc.Driver
    username: root
    password: thgXXXXXX!
server:
  port: 8081

就比如上面的配置,不需要注入任何的bean,就可以直接在代码中使用

    @Autowired
    JdbcTemplate jdbcTemplate;
属性嵌套
app.name=MyApp
app.description=${app.name} 
Yaml文件 基本语法

对象:

father:
  child1: Jack
  child2: Bob

数组:

animals:
  - Cat
  - Dog
  - Goldfish

或者

animals: [ 'Cat', 'Dog', 'Goldfish' ]

null值:

用~表示null

@ConfigurationProperties实现自动装配
@ConfigurationProperties(prefix = "my-person")
@Component
@Data
public class Person {
    private String userName;
    private Boolean boss;
    private Date birth;
    private Integer age;
    private Pet pet;
    private String[] interests;
    private List animal;
    private Map score;
    private Set salarys;
    private Map> allPets;
}
my-person:
  user-name: CodeTiger
  boss: true
  birth: 1996/11/29
  # 可以使用random来生成各种不同类型的随机值
  age: ${random.int}
  pet:
    name: tomcat
    weight: 100
  interests: [basketball, football]
  animal:
    - jerry
    - tom
  score:
    english:
      first: 30
      second: 40
      third: 50
    math: [131,140,148]
    chinese: {first: 128, second: 136}
    salarys: [3999,4999.98,5999.99]
    allPets:
      sick:
        - {name: tom}
        - {name: jerry,weight: 47}
      health: [{name: mario,weight: 47}]

注意:@ConfigurationProperties的本质是使用setter注入,所以必须要有setter方法不然没法注入

关于引入其他yaml文件的问题

我们可以注意到,当我们要引用其他配置文件时,使用@PropertySource注解来引用

但是这个注解无法配置yaml文件,所以有两种解决方案

  • 其他配置文件全部用properties来实现
  • 自己实现factory来转换yaml

自定义factory如下

import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
import org.springframework.core.env.PropertiesPropertySource;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.support.EncodedResource;
import org.springframework.core.io.support.PropertySourceFactory;
import org.springframework.lang.Nullable;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;

public class YamlPropertySourceFactory implements PropertySourceFactory {
    @Override
    public PropertySource createPropertySource(@Nullable String name, EncodedResource resource) throws IOException {
        Properties propertiesFromYaml = loadYamlIntoProperties(resource);
        String sourceName = name != null ? name : resource.getResource().getFilename();
        return new PropertiesPropertySource(sourceName, propertiesFromYaml);
    }

    private Properties loadYamlIntoProperties(EncodedResource resource) throws FileNotFoundException {
        try {
            YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
            factory.setResources(resource.getResource());
            factory.afterPropertiesSet();
            return factory.getObject();
        } catch (IllegalStateException e) {
            // for ignoreResourceNotFound
            Throwable cause = e.getCause();
            if (cause instanceof FileNotFoundException)
                throw (FileNotFoundException) e.getCause();
            throw e;
        }
    }
}

使用时:

@Component
@PropertySource(value = "my.yaml" , factory = YamlPropertySourceFactory.class)
@ConfigurationProperties(prefix = "user")
@Data
public class User {
    private int age;
    private String name;
}
Spring配置 Maven依赖 spring核心
        
            org.springframework
            spring-core
            5.3.20
        
        
            org.springframework
            spring-beans
            5.3.20
        
        
            org.springframework
            spring-context
            5.3.20
        
SpringBoot核心
        
            org.springframework.boot
            spring-boot-starter-web
        

        
            org.springframework.boot
            spring-boot-devtools
            runtime
            true
        
        
            org.springframework.boot
            spring-boot-starter-test
            test
        
JDBC以及mysql
        //用spring时用这个
				
            org.springframework
            spring-jdbc
            5.3.20
        

				//用springboot用这个
        
            org.springframework.boot
            spring-boot-starter-jdbc
        

        
            mysql
            mysql-connector-java
            8.0.25
        
配置JDBC

spring其实经历了从xml->config->springboot的过程,所以配置数据库连接也有三种方式

xml原始版

	
		
		
		
		
	

	
	
		
	

	
	
		
			
				classpath:spring/dbconfig.properties
			
		
	
	
config版本

我们看到xml配置中

  • propertyConfigurer可以用 @PropertySource(“classpath:/dbconfig.properties”)代替
url=jdbc:mysql://sh-cynosdbmysql-grp-bbhdi89q.sql.tencentcdb.com:21590/pic?serverTimezone=UTC
driverClassName=com.mysql.jdbc.Driver
password=thg1998913!
user=root
@Configuration
@ComponentScan(basePackages = {"com.thg.entity"})
@PropertySource(value = {"dbconfig.properties"})
public class Config {
    @Autowired
    DriverManagerDataSource dataSource;
    @Bean
    public DriverManagerDataSource dataSource(@Value("${url}") String url,@Value("${driverClassName}") String driverClassName,@Value("${user}")String username, @Value("${password}")String passwd){
        DriverManagerDataSource database = new DriverManagerDataSource() ;
        database.setUrl(url); //设置url
        database.setDriverClassName(driverClassName);
        database.setUsername(username); //设置账号
        database.setPassword(passwd); //设置密码
        return database;
    }
    @Bean
    public JdbcTemplate jdbcTemplate(){
        return new JdbcTemplate(dataSource);
    }
}

这里有一个需要注意的地方

就是@Value(“${user}”)String username

我开始是使用@Value(“${username}”)String username

后面一直连接不上的原因是无论你怎么改变dbconfig.properties的内容始终username永远定格在"thg"

我就怀疑是spring内置了一个变量叫username,导致我@Value出来的不是我properties文件中的内容

于是我将username改为user后发现可以成功连接上

springboot配置

我们知道springboot自动装配

使用application.properties配置

spring.datasource.url=jdbc:mysql://sh-cynosdbmysql-grp-bbhdi89q.sql.tencentcdb.com:21590/pic?serverTimezone=UTC
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.password=thg1998913!
spring.datasource.username=root

使用yaml配置其实是一样的不在累叙

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1028501.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号