01-spring 基础和组件使用

Spring

一、Spring简介

spring体系

模块名称功能特点
Spring CoreSpring核心,它是框架最基础的部分,提供IOC和依赖注入特性
Spring ContextSpring上下文容器,它是BeanFactory功能加强的一个子接口
Spring Web它提供Web应用开发的支持
Spring MVC它针对Web应用中MVC思想的实现
Spring DAO提供对JDBC抽象层,简化了JDBC编码,同时,编码更具有健壮性。
Spring ORM它支持用于流行的ORM框架的整合,比如:Spring + Hibernate、Spring + iBatis、Spring + JDO的整合等等。
Spring AOPAOP即,面向切面编程,它提供了与AOP联盟兼容的编程实现

二、配置文件声明bean

2.1 配置文件

<?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.xsd">

	<bean id="person" class="com.enjoy.cap1.Person">
		<property name="name" value="james"></property>
		<property name="age" value="19"></property>
	</bean>
</beans>

2.2 代码

public class MainTest1 { 
	public static void main(String args[]){
		//加载配置文件
		ApplicationContext app = new ClassPathXmlApplicationContext("beans.xml");
		//获取bean
		Person person = (Person) app.getBean("person");
		System.out.println(person);
	}
}

三、Configuration注解

  • 声明该注解的是配置类,等价于配置文件声明bean,代码如下:
@Configuration
public class MainConfig {
	//定义bean
	@Bean("beanName")
	public Person person(){
		return new Person("james",20);
	}
}

3.1 代码

public class MainTest2 { 
	public static void main(String args[]){
		//加载配置文件
		//ApplicationContext app = new ClassPathXmlApplicationContext("beans.xml");
		
		ApplicationContext app = new AnnotationConfigApplicationContext(MainConfig.class);
		
		//获取bean
		Person person = (Person) app.getBean("beanName");
		
		System.out.println(person);
		
		String[] namesForBean = app.getBeanNamesForType(Person.class);
		for(String name:namesForBean){
			System.out.println(name);
		}
		
		
	}
}

四、ComponentScan

4.1 ComponentScan扫描路径,指定bean扫描范围

@Configuration
//扫描指定路径下的bean
@ComponentScan(value="com.enjoy.cap2")
public class Cap2MainConfig {
	//定义的bean一定会加载 
	@Bean
	public Person person01(){
		return new Person("james",20);
	}
}

4.2 扫描过滤器

@Configuration
@ComponentScan(value="com.enjoy.cap2", includeFilters={		
		@Filter(type=FilterType.ANNOTATION, classes={Controller.class})		
}, useDefaultFilters=false)
public class Cap2MainConfig {
}

4.3 自定义过滤规则

@Configuration
@ComponentScan(value="com.enjoy.cap2", includeFilters={		
		@Filter(type=FilterType.CUSTOM, classes={JamesTypeFilter.class})		
}, useDefaultFilters=false)
public class Cap2MainConfig {
}
  • JamesTypeFilter是自定义的过滤规则,实现TypeFilter接口

五、scope

5.1 scope指定bean的作用范围

@Configuration
public class Cap3MainConfig {
	//给容器中注册一个bean, 类型为返回值的类型, 默认是单实例
	/*
	 * prototype:多实例: IOC容器启动的时候,IOC容器启动并不会去调用方法创建对象, 而是每次获取的时候才会调用方法创建对象
	 * singleton:单实例(默认):IOC容器启动的时候会调用方法创建对象并放到IOC容器中,以后每次获取的就是直接从容器中拿(大Map.get)的同一个bean
	 * request: 主要针对web应用, 递交一次请求创建一个实例(使用不多)
	 * session:同一个session创建一个实例(使用不多)
	 */
	@Scope("prototype")
	@Bean
	public Person person(){
		return new Person("james",20);
	}
}

六、Lazy延迟加载

  • Lazy延迟bean加载的时机
@Configuration
public class Cap4MainConfig {
	 /*
	 * 立即加载: 主要针对单实例bean:默认在容器启动的时候创建对象(默认)
	 * 懒加载: 容器启动时候不创建对象,仅当第一次使用(获取)bean的时候才创
	 * 建被初始化(加上注解的效果,减少Spring容器启动的加载时间)
	 */
	@Lazy
	@Bean
	public Person person(){
		System.out.println("给容器中添加person.......");
		return new Person("james",20);
	}
}

七、Conditional

Conditional按照条件注册bean


 /**
 *条件类需要实现Condition接口,返回boolean值作为是否加载的判断标准
 *如此达到按照指定条件加载bean的目的
 */
@Conditional(MyCondition.class)
@Bean
public MyBean myBean(){
    return new MyBean();
}

public class MyCondition implements Condition{
    
    if(xxx){
        return false;
    }    
    return true;
}

八、Import

  • Import注册bean
/**
* @Import(A.class)
*/

九、注册bean的方法小结

注册bean的方法备注
包扫描+注解标注指定包扫描路径,路径下的类使用@Componount或者相关注解标注
@Bean导入第三方类或者包的组件(相对比较简单)
@ImportImport的参数可以是一个类,也可以是一个ImportSelector接口,也可以是ImportBeanDefinitionRegistrar接口
实现FactoryBean接口getObject返回bean对象

代码

  • 下面代码涵盖了多种bean的创建方式,包括@Bean注解,@Import,MyImportSelector,MyImportBeanDefinitionRegistrar,FactoryBean
    //配置类
    @Configuration
    @Import(value = {Dog.class, Cat.class, MyImportSelector.class, MyImportBeanDefinitionRegistrar.class })
    public class Cap6MainConfig {
    /*
     * 给容器中注册组件的方式
     * 1,@Bean: [导入第三方的类或包的组件],比如Person为第三方的类, 需要在我们的IOC容器中使用
     * 2,包扫描+组件的标注注解(@ComponentScan:  @Controller, @Service  @Reponsitory  @ Componet),一般是针对 我们自己写的类,使用这个
     * 3,@Import:[快速给容器导入一个组件] 注意:@Bean有点简单
     *      a,@Import(要导入到容器中的组件):容器会自动注册这个组件,bean 的 id为全类名
     *      b,ImportSelector:是一个接口,返回需要导入到容器的组件的全类名数组
     *      c,ImportBeanDefinitionRegistrar:可以手动添加组件到IOC容器, 所有Bean的注册可以使用BeanDifinitionRegistry
     *          写JamesImportBeanDefinitionRegistrar实现ImportBeanDefinitionRegistrar接口即可
     *  4,使用Spring提供的FactoryBean(工厂bean)进行注册
     */
    //容器启动时初始化person的bean实例
    @Bean("person")
    public Person person() {
        return new Person("kobe", 20);
    }

    @Bean
    public MyFactoryBean myFactoryBean(){
        return new MyFactoryBean();
    }
}

public class Dog {

}

public class Cat {

}

public class MyImportSelector implements ImportSelector{
	@Override
	public String[] selectImports(AnnotationMetadata importingClassMetadata){
		//返回全类名的bean
		return new String[]{"com.intellif.ch6.bean.Fish","com.intellif.ch6.bean.Tiger"};
	}
}



public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {

    /**
     *AnnotationMetadata:当前类的注解信息
     *BeanDefinitionRegistry:BeanDefinition注册类
     *    把所有需要添加到容器中的bean加入;
     *    @Scope
     */
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        boolean bean1 = registry.containsBeanDefinition("com.intellif.ch6.bean.Dog");
        boolean bean2 = registry.containsBeanDefinition("com.intellif.ch6.bean.Cat");
        //如果Dog和Cat同时存在于我们IOC容器中,那么创建Pig类, 加入到容器
        //对于我们要注册的bean, 给bean进行封装,
        if (bean1 && bean2) {
            RootBeanDefinition beanDefinition = new RootBeanDefinition(Pig.class);
            registry.registerBeanDefinition("pig", beanDefinition);
        }
    }

}

public class MyFactoryBean implements FactoryBean<Monkey> {

    @Override
    public Monkey getObject() throws Exception {
        return new Monkey();
    }

    @Override
    public Class<?> getObjectType() {
        return Monkey.class;
    }

    @Override
    public boolean isSingleton() {
        return true;
    }
}

测试代码:
public class Ch6Test {

    @Test
    public void test01() {

        ApplicationContext app = new AnnotationConfigApplicationContext(Cap6MainConfig.class);
        System.out.println("------cut-off---------");

        //2.获取Person类型的bean的名字
        String[] names = app.getBeanDefinitionNames();
        //2.遍历bean的名称
        for (String name : names) {
            System.out.println(name+"---"+app.getBean(name));

        }
    }
}

注意在使用FactoryBean的方式注册bean的时候,bean的名字是下面这个方法的名字,但是对应bean的类型是MyFactoryBean
的getObject方法返回的类型
    @Bean
    public MyFactoryBean myFactoryBean(){
        return new MyFactoryBean();
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值