spring注解开发入门版(ioc)

注解开发和配置文件开发转化说明和对比

                                                                             原spring开发                                                                             注解开发
Spring 的配置文件  applicationContext.xml@Configuration注解注释的类

bean的注入

<bean id="helloWorld" class="com.hd.spring.HelloWorld">
        <property name="user" value="Jerry"></property>
   </bean>

@Bean
    public Person person(){
        return new Person("user", Jerry);
    }

赋值还可以用@value注解赋值

@Bean
    public Person person(){
        return new Person();
    }

person {

 

  @Value("张三")
    private String name;
    @Value("20")
    private Integer age;

 

}

 

加载配置文件获取bean用

ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
       HelloWorld bean = (HelloWorld) applicationContext.getBean("helloWorld");

ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
        Person bean = applicationContext.getBean(Person.class);

MainConfig这个类是@Configuration注释的类

原扫描包注入

<context:component-scan base-package="com.hd.cyz"></context:component-scan>

<context:component-scan> 下可以拥有若干个

<context:include-filter> 和

<context:exclude-filter> 子节点

用指定节点<context:include-filter>配置时需要禁用<context:component-scan> 默认的全部扫描

<context:component-scan base-package="xxx.xxx" use-default-filters="false">

@ComponentScans(
        value = {
                @ComponentScan(value="com.hd.cyz",includeFilters = {
                       @Filter(type=FilterType.ANNOTATION,classes={Controller.class}))
                },useDefaultFilters = false)    
        }
        )

@ComponentScan  value:指定要扫描的包
excludeFilters = Filter[] :指定扫描的时候按照什么规则排除那些组件
includeFilters = Filter[] :指定扫描的时候只需要包含哪些组件
FilterType.ANNOTATION:按照注解

FilterType.ASSIGNABLE_TYPE:按照给定的类型;
FilterType.ASPECTJ:使用ASPECTJ表达式
FilterType.REGEX:使用正则指定
FilterType.CUSTOM:使用自定义规则  (详情见下文

useDefaultFilters 相当于标签中的use-default-filters="false"属性 默认true

@ComponentScans中可以配置多个 @ComponentScan 需要扫描一个时用@ComponentScan

加的位置在配置类上

<!-- 具体的作用域需要在 scope 属性中定义 --> <bean id="XXX" class="com.XXX.XXXXX" scope="XXXX" />

singleton:单例模式,在整个Spring IoC容器中,使用singleton定义的Bean将只有一个实例

prototype:原型模式,每次通过容器的getBean方法获取prototype定义的Bean时,都将产生一个新的Bean实例

request:对于每次HTTP请求,使用request定义的Bean都将产生一个新实例,即每次HTTP请求将会产生不同的Bean实例。只有在Web应用中使用Spring时,该作用域才有效

session:对于每次HTTP Session,使用session定义的Bean豆浆产生一个新实例。同样只有在Web应用中使用Spring时,该作用域才有效

globalsession:每个全局的HTTP Session,使用session定义的Bean都将产生一个新实例。典型情况下,仅在使用portlet context的时候有效。同样只有在Web应用中使用Spring时,该作用域才有效

  其中比较常用的是singleton和prototype两种作用域。对于singleton作用域的Bean,每次请求该Bean都将获得相同的实例。容器负责跟踪Bean实例的状态,负责维护Bean实例的生命周期行为;如果一个Bean被设置成prototype作用域,程序每次请求该id的Bean,Spring都会新建一个Bean实例,然后返回给程序。在这种情况下,Spring容器仅仅使用new 关键字创建Bean实例,一旦创建成功,容器不在跟踪实例,也不会维护Bean实例的状态。

  如果不指定Bean的作用域,Spring默认使用singleton作用域。Java在创建Java实例时,需要进行内存申请;销毁实例时,需要完成垃圾回收,这些工作都会导致系统开销的增加。因此,prototype作用域Bean的创建、销毁代价比较大。而singleton作用域的Bean实例一旦创建成功,可以重复使用。因此,除非必要,否则尽量避免将Bean被设置成prototype作用域。

@scope完成bean的作用域配置默认是单例模式(singleton)如果需要设置的话可以修改对应值与以上提到的一致例如:@scope(“prototype”)

Bean 的声明里设置 init-method destroy-method 属性, Bean 指定初始化和销毁方法

 * 1)、指定初始化和销毁方法;
 *         通过@Bean指定init-method和destroy-method;

                                          @Bean(initMethod="init",destroyMethod="detory")
                                                    public Car car(){
                                                    return new Car();
                                                              }
 * 2)、通过让Bean实现InitializingBean(定义初始化逻辑),
 *                 DisposableBean(定义销毁逻辑);
 * 3)、可以使用JSR250;
 *         @PostConstruct:在bean创建完成并且属性赋值完成;来执行初始化方法
 *         @PreDestroy:在容器销毁bean之前通知我们进行清理工作
 * 4)、BeanPostProcessor【interface】:bean的后置处理器;
 *         在bean初始化前后进行一些处理工作;
 *         postProcessBeforeInitialization:在初始化之前工作
 *         postProcessAfterInitialization:在初始化之后工作
 * 

应用外部文件并赋值

<context:property-placeholder location="classpath:dbconfig.properties" />

        <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
        <property name="driverClass" value="${jdbc.driverClass}"></property>
        <property name="user" value="${jdbc.user}"></property>
        <property name="password" value="${jdbc.password}"></property>

注解用在配置类上面@PropertySource(value={"classpath:/dbconfig.properties"})

获取配置文件中的值

@Value("${key}")注解加在bean的属性上

 @Profile注解(详情见下文
<!-- 使 AspectJ 的注解起作用 -->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
开启基于注解的aop模式;@EnableAspectJAutoProxy
<!-- 配置事务管理器 -->
    <bean id="transactionManager" 
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    
    <!-- 启用事务注解 -->
    <tx:annotation-driven transaction-manager="transactionManager"/>
给方法上标注 @Transactional 表示当前方法是一个事务方法;
  @EnableTransactionManagement 开启基于注解的事务管理功能;
 
 配置事务管理器来控制事务;
 //注册事务管理器在容器中
    @Bean
    public PlatformTransactionManager transactionManager() throws Exception{
        return new DataSourceTransactionManager(dataSource());
    }

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

给容器中导入组件的其他方法
@Import[快速给容器中导入一个组件]
     *         1)、@Import(要导入到容器中的组件);容器中就会自动注册这个组件,id默认是全类名
     *         2)、ImportSelector:返回需要导入的组件的全类名数组;   需要自己写实现根据自己的需求装入组件
     *         3)、ImportBeanDefinitionRegistrar:手动注册bean到容器中
使用Spring提供的 FactoryBean(工厂Bean);
     *         1)、默认获取到的是工厂bean调用getObject创建的对象
     *         2)、要获取工厂Bean本身,我们需要给id前面加一个

自定义组件想要使用Spring容器底层的一些组件(ApplicationContext,BeanFactory,xxx)
 *         自定义组件实现xxxAware;在创建对象的时候,会调用接口规定的方法注入相关组件;Aware;
 *         把Spring底层一些组件注入到自定义的Bean中;
 *         xxxAware:功能使用xxxProcessor;
 *             ApplicationContextAware==》ApplicationContextAwareProcessor;

条件构造器编写Condition

@Conditional({Condition}) : 按照一定的条件进行判断,满足条件给容器中注册bean

@Conditional(LinuxCondition.class)
    @Bean("linus")
    public Person person02(){
        return new Person("linus", 48);
    }

 

条件构造器

public class LinuxCondition implements Condition {

    /**
     * ConditionContext:判断条件能使用的上下文(环境)
     * AnnotatedTypeMetadata:注释信息
     */
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        // TODO是否linux系统
        //1、能获取到ioc使用的beanfactory
        ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
        //2、获取类加载器
        ClassLoader classLoader = context.getClassLoader();
        //3、获取当前环境信息
        Environment environment = context.getEnvironment();
        //4、获取到bean定义的注册类
        BeanDefinitionRegistry registry = context.getRegistry();
        
        String property = environment.getProperty("os.name");
        
        //可以判断容器中的bean注册情况,也可以给容器中注册bean
        boolean definition = registry.containsBeanDefinition("person");
        if(property.contains("linux")){
            return true;
        }
        
        return false;
    }

自定义filter编写

实现 implements TypeFilter重写match方法

match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)参数说明

 * metadataReader:读取到的当前正在扫描的类的信息
 * metadataReaderFactory:可以获取到其他任何类信息的

举例

public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)
			throws IOException {
		// TODO Auto-generated method stub
		//获取当前类注解的信息
		AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
		//获取当前正在扫描的类的类信息
		ClassMetadata classMetadata = metadataReader.getClassMetadata();
		//获取当前类资源(类的路径)
		Resource resource = metadataReader.getResource();
		
		String className = classMetadata.getClassName();
		System.out.println("--->"+className);
		if(className.contains("hd")){
			return true;
		}
		return false;
	}

Profile用法详解

/**
 * Profile:
 *         Spring为我们提供的可以根据当前环境,动态的激活和切换一系列组件的功能;
 * 
 * 开发环境、测试环境、生产环境;
 * 数据源:(/A)(/B)(/C);
 * 
 * 
 * @Profile:指定组件在哪个环境的情况下才能被注册到容器中,不指定,任何环境下都能注册这个组件
 * 
 * 1)、加了环境标识的bean,只有这个环境被激活的时候才能注册到容器中。默认是default环境
 * 2)、写在配置类上,只有是指定的环境的时候,整个配置类里面的所有配置才能开始生效
 * 3)、没有标注环境标识的bean在,任何环境下都是加载的;
 */

@PropertySource("classpath:/dbconfig.properties")
@Configuration
public class MainConfigOfProfile implements EmbeddedValueResolverAware //第三种获取配置文件的值{
    
    @Value("${db.user}")//第一种获取配置文件的值
    private String user;
    
    private StringValueResolver valueResolver;//第三种获取配置文件的值
    
    private String  driverClass;//第三种获取配置文件的值
    
    

    @Profile("test")
    @Bean("testDataSource")
    public DataSource dataSourceTest(@Value("${db.password}")String pwd) throws Exception{//第二种获取配置文件的值
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setUser(user);
        dataSource.setPassword(pwd);
        dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test");
        dataSource.setDriverClass(driverClass);
        return dataSource;
    }
    
    
    @Profile("dev")
    @Bean("devDataSource")
    public DataSource dataSourceDev(@Value("${db.password}")String pwd) throws Exception{
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setUser(user);
        dataSource.setPassword(pwd);
        dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/dev");
        dataSource.setDriverClass(driverClass);
        return dataSource;
    }
    
    @Profile("prod")
    @Bean("prodDataSource")
    public DataSource dataSourceProd(@Value("${db.password}")String pwd) throws Exception{
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setUser(user);
        dataSource.setPassword(pwd);
        dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/prod");
        
        dataSource.setDriverClass(driverClass);
        return dataSource;
    }

    @Override
    public void setEmbeddedValueResolver(StringValueResolver resolver) {//第三种获取配置文件的值
        // TODO Auto-generated method stub
        this.valueResolver = resolver;
        driverClass = valueResolver.resolveStringValue("${db.driverClass}");
    }

}

 

上面是写配置文件写法 

用法

//1、使用命令行动态参数: 在虚拟机参数位置加载 -Dspring.profiles.active=test
    //2、代码的方式激活某种环境;
    @Test
    public void test01(){
        AnnotationConfigApplicationContext applicationContext = 
                new AnnotationConfigApplicationContext();
        //1、创建一个applicationContext
        //2、设置需要激活的环境
        applicationContext.getEnvironment().setActiveProfiles("dev");
        //3、注册主配置类
        applicationContext.register(MainConfigOfProfile.class);
        //4、启动刷新容器
        applicationContext.refresh();
        
        
        String[] namesForType = applicationContext.getBeanNamesForType(DataSource.class);
        for (String string : namesForType) {
            System.out.println(string);
        }
        
        applicationContext.close();
    }

 

 

spring注解开发开启aop

开启基于注解的aop模式;@EnableAspectJAutoProxy

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值