Spring-基础学习02

【第一章】常用注解【重点】

前提:必须要开始spring注解扫描<context:component-scan base-package=“com.itheima”/>

1 创建bean对象的基础注解【重要】

1.1 @Component、@Controller、@Service、@Repository的作用【重要】
Component [kəmˈpəʊnənt]n. 组成部分;成分;组件,元件

Repository  [rɪˈpɒzətri]n. 贮藏室,仓库;知识库;智囊团

作用:相当于<bean id="" class="">,用于创建bean对象添加到Spring容器中

说明:这三个注解的作用是一样的,使用在类上面,都表示将自己定义的类交给Spring创建对象,保持到Spring容器中。只不过spring推荐我们在web层使用 @Controller注解,在service层使用@Service注解,在dao层使用@Repository注解。如果bean不在三层结构中,那么就是@Component。例如:

@Service("studentService") //参数为bean的名称
public class StudentServiceImpl implements StudentService {
  //...
}
@Repository("userDao")
public class UserDaoImpl implements UserDao {
  //...
}
1.2 @Scope注解的作用【了解】

作用:定义bean是单例还是多例

@Service("studentService") //参数为bean的名称
@Scope("singleton") //默认就是单例的,prototype表示多例
public class StudentServiceImpl implements StudentService {
  //...
}
1.3 定义生命周期方法的注解【了解】

注意:如果jdk的版本高于1.8就需要额外导入一个依赖

<dependency>
  <groupId>org.apache.tomcat</groupId>
  <artifactId>annotations-api</artifactId>
  <version>6.0.29</version>
</dependency>

@PostConstruct、@PreDestroy用在方法上面,@PostConstruct定义初始化方法,@PreDestroy定义销毁的方法。

2 依赖注入注解【重要】

重点掌握@AutoWired注解,次掌握@qualifier和@Value注解,

作用:相当于<property name="" ref="" />用于给bean的属性注入数据。

==**@Autowired : **==自动按照类型注入,如果spring容器中同类型的对象有多个,那么按照参数名匹配id值,如果匹配不上就报错。推荐使用@Qualifier指定要匹配的bean的id值

@Qualifier("") : 用来指定匹配的bean的id值,@Qualifier可以用在成员变量上(必须要和@Autowired一起使用,不能单独使用),但是可以单独用在方法参数上。

==@Value(""):==用来注入普通类型,保持String类型,参数可以使用EL表达式

@Service("userService")
public class UserServiceImpl implements UserService {
    @Autowired  
    @Qualifier("userDao") 
    private UserDao userDao;

    @Value("com.mysql.jdbc.Driver")
    private String driverClassName;
  
}

3 纯注解开发【理解】

【第一步】使用配置类代替配置文件

**@Configuration :**用在类上,表示该类是一个spring配置类,代替applicationContext.xml配置文件

**@ComponentScan(""):**配置spring包扫描,相当于<context:component-scan base-package=“com.itheima”/>

**@PropertySource(""):**引入properties属性文件,相当于<context:property-placeholder location=“classpath:jdbc.properties”/>

@Configuration //用在类上,表示该类是一个spring配置类,代替applicationContext.xml配置文件
@ComponentScan("com.itheima")//相当于<context:component-scan base-package="com.itheima"/>开启spring注解扫描
@PropertySource("classpath:jdbc.properties")//<context:property-placeholder location="classpath:jdbc.properties"/>引入属性文件
public class SpringConfiguration {

}
【第二步】定义方法将第三方类交给spring管理

@Bean注解的作用:将方法的返回值存到spring容器中,可以指定名称,如果没有指定,默认名称就是方法名,方法名首字母小写。

@Configuration //用在类上,表示该类是一个spring配置类,代替applicationContext.xml配置文件
@ComponentScan("com.itheima")//相当于<context:component-scan base-package="com.itheima"/>开启spring注解扫描
@PropertySource("classpath:jdbc.properties")//<context:property-placeholder location="classpath:jdbc.properties"/>引入属性文件
public class SpringConfiguration {
    @Value("${jdbc.driver}")
    private String driverClassName;
    @Value("${jdbc.url}")
    private String url;
    @Value("${jdbc.username}")
    private String username;
    @Value("${jdbc.password}")
    private String password;

    /*
        <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
            <property name="driverClassName" value="${jdbc.driver}"/>
            <property name="url" value="${jdbc.url}"/>
            <property name="username" value="${jdbc.username}"/>
            <property name="password" value="${jdbc.password}"/>
        </bean>
        使用注解配置第三方类
     */
    @Bean("dataSource") //也可以不指定名称,默认名称是方法名首字母小写
    public DataSource getDataSource(){
        DruidDataSource ds=new DruidDataSource();
        ds.setDriverClassName(driverClassName);
        ds.setUrl(url);
        ds.setUsername(username);
        ds.setPassword(password);
        return ds;
    }
}

【第三步】可选操作,引入分配置类

**@Import({JdbcConfig.class}):**表示引入一个名字叫做JdbcConfig的配置类

@Configuration //用在类上,表示该类是一个spring配置类,代替applicationContext.xml配置文件
@ComponentScan("com.itheima")//相当于<context:component-scan base-package="com.itheima"/>开启spring注解扫描
@PropertySource("classpath:jdbc.properties")//<context:property-placeholder location="classpath:jdbc.properties"/>引入属性文件
@Import({JdbcConfig.class})//<!--<import resource="classpath:xxxxx.xml"/>-->
public class SpringConfiguration {
  
}

上午内容回顾

1 创建Bean对象存到Spring容器中的注解【掌握】
	@Controller、@Service、@Repository、@Component、@Bean
	
	使用说明:
	@Controller、@Service、@Repository(较少使用)、@Component用在类上的,给自定义类配置,可以用参数指定bean的名称
	@Bean(较少使用)在配置类中用在方法上,给第三方类配置,将方法的返回值对象存的Spring容器中
	
2 依赖注入的注解【掌握】
	注入引用类型:
		@Autowired:表示按照类型自动注入对象,如果有多个同类型对象,则默认按照变量名和id值匹配。
		@Qualifier("bean的名称"):集合@Autowired在变量上一起使用,指定使用哪个名称的对象。
	注入普通类型:(包括String字符串)
		@Value(""):支持EL表达式
		
3 其他注解【了解】,针对纯注解方式,在配置类中使用。
	@Configuration :表示这个类是一个配置类
	@ComponentScan(""):配置包扫描
	@PropertySource(""):引入属性文件
	@Import(""):引入分配置类

【第二章】bean加载控制【了解】

3.1)依赖加载

(1)@DependsOn

  • 名称:@DependsOn

  • 类型:类注解、方法注解

  • 位置:bean定义的位置(类上或方法上)

  • 作用:控制bean的加载顺序,使其在指定bean加载完毕后再加载

  • 范例:

    @DependsOn("beanId")
    public class ClassName {
    }
    
  • 说明:

    • 配置在方法上,使@DependsOn指定的bean优先于@Bean配置的bean进行加载

    • 配置在类上,使@DependsOn指定的bean优先于当前类中所有@Bean配置的bean进行加载

    • 配置在类上,使@DependsOn指定的bean优先于@Component等配置的bean进行加载

  • 相关属性

    • value(默认):设置当前bean所依赖的bean的id

(2)@Order

  • 名称:@Order

  • 类型:配置类注解

  • 位置:配置类定义的位置(类上)

  • 作用:控制配置类的加载顺序

  • 范例:

    @Order(1)
    public class SpringConfigClassName {
    }
    

(3)@Lazy

  • 名称:@Lazy

  • 类型:类注解、方法注解

  • 位置:bean定义的位置(类上或方法上)

  • 作用:控制bean的加载时机,使其延迟加载

  • 范例:

    @Lazy
    public class ClassName {
    }
    

3.2)依赖加载应用场景

@DependsOn

  • 微信订阅号,发布消息和订阅消息的bean的加载顺序控制

  • 双11活动期间,零点前是结算策略A,零点后是结算策略B,策略B操作的数据为促销数据。策略B加载顺序与促销数据的加载顺序

@Lazy

  • 程序灾难出现后对应的应急预案处理是启动容器时加载时机

@Order

  • 多个种类的配置出现后,优先加载系统级的,然后加载业务级的,避免细粒度的加载控制

【第三章】注解整合mybatis和junit案例【重点】

1 主配置类

@Configuration //表示该类是一个配置类
@ComponentScan("com.itheima")//<context:component-scan base-package="com.itheima.service"/>
@PropertySource("classpath:jdbc.properties")//<context:property-placeholder location="classpath:jdbc.properties"/>
@Import({JdbcConfig.class,MybatisConfig.class})
public class SpringConfiguration {

}

2 分配置类

  • JdbcConfig配置类
public class JdbcConfig {
  @Value("${jdbc.driver}")
  private String driverClassName;
  @Value("${jdbc.url}")
  private String url;
  @Value("${jdbc.username}")
  private String username;
  @Value("${jdbc.password}")
  private String password;

  /*
        <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
            <property name="driverClassName" value="${jdbc.driver}"/>
            <property name="url" value="${jdbc.url}"/>
            <property name="username" value="${jdbc.username}"/>
            <property name="password" value="${jdbc.password}"/>
        </bean>
     */
  @Bean("dataSource")  //方法的返回值对象在Spring容器
  public DataSource getDataSource(){
    DruidDataSource ds=new DruidDataSource();
    ds.setDriverClassName(driverClassName);
    ds.setUrl(url);
    ds.setUsername(username);
    ds.setPassword(password);
    return ds;
  }
}
  • MybatisConfig配置类
public class MybatisConfig {
  /*
   <bean class="org.mybatis.spring.SqlSessionFactoryBean">
     <!--必须有-->
     <property name="dataSource" ref="dataSource"/>
     <!--配置别名-->
     <property name="typeAliasesPackage" value="com.itheima.bean"/>
     <!--配置mybatis的核心配置文件的位置,核心配置文件中也可以设置别名、映射文件位置等操作-->
     <!--<property name="configLocation" value="classpath:MybatisConfig.xml"/>-->
     <!--如果映射文件和mapper接口在同一个包下-->
     <!--<property name="mapperLocations" value="classpath:StudentMapper.xml"/>-->
   </bean>
   */
  @Bean  //这个方法是由Spring容器调用,如果方法有参数,那么Spring会在容器中找对应的值/对象,参数按照类型匹配,相当于省略了@Autowired
  public SqlSessionFactoryBean getSqlSessionFactoryBean(DataSource dataSource){
    SqlSessionFactoryBean ssfb=new SqlSessionFactoryBean();
    ssfb.setDataSource(dataSource);
    ssfb.setTypeAliasesPackage("com.itheima.bean");
    return ssfb;
  }

  /*
        <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
            <!--扫描mapper所在的包,映射文件需要和包在一起,如果不在一起,就需要在SqlSessionFactoryBean中配置额外指定-->
            <property name="basePackage" value="com.itheima.mapper"/>
        </bean>
     */
  @Bean
  public MapperScannerConfigurer getMapperScannerConfigurer(){
    MapperScannerConfigurer msc=new MapperScannerConfigurer();
    msc.setBasePackage("com.itheima.mapper");
    return msc;
  }
}

3 StudentServiceImpl注解配置

/*
    <!--配置service-->
    <bean id="studentService" class="com.itheima.service.impl.StudentServiceImpl">
        <property name="mapper" ref="studentMapper"/>
    </bean>
 */
@Service("studentService")
public class StudentServiceImpl implements StudentService {
  @Autowired
  private StudentMapper mapper; //注入的是mapper的代理对象
  //...
}

4 实现类代码测试

@Test
public void test1() throws IOException {
  //创建Spring容器对象
  //ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
  ApplicationContext ac=new AnnotationConfigApplicationContext(SpringConfiguration.class);
  //获取service对象
  StudentService studentService = ac.getBean("studentService", StudentService.class);
  //执行操作,调用service的方法
  List<Student> list = studentService.selectAll();
  list.forEach(stu-> System.out.println(stu));
}

5 Spring整合junit单元测试

注意:junit的依赖至少要是4.12版本,可以是4.13等版本,否则出现如下异常:

在这里插入图片描述

【第一步】导入整合的依赖坐标spring-test
<!--junit-->
<dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>4.12</version>
</dependency>
<!--spring整合junit-->
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-test</artifactId>
  <version>5.1.5.RELEASE</version>
</dependency>
【第二步】使用spring提供的类加载器替换单元测试原有的类加载器
【第三步】告诉单元测试spring的配置文件或者配置类
@RunWith(SpringJUnit4ClassRunner.class)
//@ContextConfiguration(locations = "classpath:applicationContext.xml") //加载配置文件
@ContextConfiguration(classes = {SpringConfiguration.class}) //加载配置类
public class StudentTest {
  @Autowired  //自动按照类型注入对象
  private StudentService studentService;
  
  //....
}

【第四章】IOC底层原理【了解】

5.1)IoC核心接口

在这里插入图片描述

5.2)组件扫描器

  • 开发过程中,需要根据需求加载必要的bean,排除指定bean
    在这里插入图片描述

5.3)设定组件扫描加载过滤器

  • 名称:@ComponentScan

  • 类型:类注解

  • 位置:类定义上方

  • 作用:设置spring配置加载类扫描规则

  • 范例:

    @ComponentScan(
        value="com.itheima",	           //设置基础扫描路径
        excludeFilters =                          //设置过滤规则,当前为排除过滤
    	@ComponentScan.Filter(            //设置过滤器
    	    type= FilterType.ANNOTATION,  //设置过滤方式为按照注解进行过滤
    	    classes=Repository.class)     //设置具体的过滤项,过滤所有@Repository修饰的bean
        )
    

​ includeFilters:设置包含性过滤器

​ excludeFilters:设置排除性过滤器

​ type:设置过滤器类型

5.4)自定义组件过滤器

  • 名称:TypeFilter

  • 类型:接口

  • 作用:自定义类型过滤器

  • 范例:

    public class MyTypeFilter implements TypeFilter {
        public boolean match(MetadataReader mr, MetadataReaderFactory mrf) throws IOException {
            ClassMetadata cm = metadataReader.getClassMetadata();
            tring className = cm.getClassName();
            if(className.equals("com.itheima.dao.impl.BookDaoImpl")){
                return false;
            }
            return false;
        }
    }
    

5.5)自定义导入器

  • bean只有通过配置才可以进入spring容器,被spring加载并控制

  • 配置bean的方式如下:

    • XML文件中使用标签配置

    • 使用@Component及衍生注解配置

  • 企业开发过程中,通常需要配置大量的bean,需要一种快速高效配置大量bean的方式

ImportSelector

  • 名称: ImportSelector

  • 类型:接口

  • 作用:自定义bean导入器

  • 范例:

    public class MyImportSelector implements ImportSelector {
        public String[] selectImports(AnnotationMetadata icm) {
            return new String[]{"com.itheima.dao.impl.AccountDaoImpl"};
        }
    }
    
    @Configuration
    @ComponentScan("com.itheima")
    @Import(MyImportSelector.class)
    public class SpringConfig {
    }
    

5.6)自定义注册器

  • 名称:ImportBeanDefinitionRegistrar

  • 类型:接口

  • 作用:自定义bean定义注册器

  • 范例:

    public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
        public void registerBeanDefinitions(AnnotationMetadata icm, BeanDefinitionRegistry r) {
            ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(r, false);
            TypeFilter tf = new TypeFilter() {
                public boolean match(MetadataReader mr, MetadataReaderFactory mrf) throws IOException {
                    return true;
                }
            };
            scanner.addIncludeFilter(tf);
            //scanner.addExcludeFilter(tf);
            scanner.scan("com.itheima");
        }
    }
    

5.7)bean初始化过程解析

在这里插入图片描述

5.8)bean初始化过程解析

  • BeanFactoryPostProcessor

    • 作用:定义了在bean工厂对象创建后,bean对象创建前执行的动作,用于对工厂进行创建后业务处理

    • 运行时机:当前操作用于对工厂进行处理,仅运行一次

  • BeanPostProcessor

    • 作用:定义了所有bean初始化前后进行的统一动作,用于对bean进行创建前业务处理与创建后业务处理

    • 运行时机:当前操作伴随着每个bean的创建过程,每次创建bean均运行该操作

  • InitializingBean

    • 作用:定义了每个bean的初始化前进行的动作,属于非统一性动作,用于对bean进行创建前业务处理

    • 运行时机:当前操作伴随着任意一个bean的创建过程,保障其个性化业务处理

  • 注意:上述操作均需要被spring容器加载放可运行

5.9)bean初始化过程解析

在这里插入图片描述

5.10)繁琐的bean初始化过程处理

  • FactoryBean
    • 对单一的bean的初始化过程进行封装,达到简化配置的目的

FactoryBean与BeanFactory区别

  • FactoryBean:封装单个bean的创建过程

  • BeanFactory:Spring容器顶层接口,定义了bean相关的获取操作

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值