spring-ioc-2

1.Bean生命周期回调--->并非springBean的生命周期

(1)初始化回调

1.bean实现org.springframework.beans.factory.InitializingBean接口

  重写void afterPropertiesSet() throws Exception;

  官方不建议使用!!!,推荐使用注解

  原因:我们建议您不要使用该InitializingBean接口,因为它会不必要地将代码耦合到Spring。或者,我们建议使用@PostConstruct注释或指定POJO初始化方法

2.annotation方式---jsr的注解非spring提供的

@PostConstruct

3.xml配置

<bean id="exampleInitBean" class="examples.ExampleBean" init-method="init"/>
public class ExampleBean {

    public void init() {
        // do some initialization work
    }
}

(2)销毁回调-->Destruction Callbacks

1.bean实现org.springframework.beans.factory.DisposableBean接口,重写

  void destroy() throws Exception;
  方法官方不推荐使用!!!!
  原因:同上
2.使用annotation

  @PreDestroy

3.xml配置

<bean id="exampleInitBean" class="examples.ExampleBean" destroy-method="cleanup"/>
public class ExampleBean {

    public void cleanup() {
        // do some destruction work (like releasing pooled connections)
    }
}

(3)定义默认的初始化和销毁的方法

pojo:

public class DefaultBlogService implements BlogService {

    private BlogDao blogDao;

    public void setBlogDao(BlogDao blogDao) {
        this.blogDao = blogDao;
    }

    // 名字任意,xml文件作出相应的声明即可
    public void init() {
        if (this.blogDao == null) {
            throw new IllegalStateException("The [blogDao] property must be set.");
        }
    }
  /*
    
  public void destory() {
        //......
    }

  */
}

config.xml:

<beans default-init-method="init">
  <!--
default-destroy-method="
destory
"
--> <bean id="blogService" class="com.something.DefaultBlogService"> <property name="blogDao" ref="blogDao" /> </bean> </beans>

2.ApplicationContextAwareBeanNameAware

(1)ApplicationContextAware

用途:

对其他bean进行编程检索。有时这种能力很有用。但是,一般情况下,您应该避免使用它,因为它将代码耦合到Spring并且不遵循Inversion of Control样式,其中协作者作为属性提供给bean。其他方法 ApplicationContext提供对文件资源的访问,发布应用程序事件和访问MessageSource。这些附加功能在附加ApplicationContext功能中描述 。

接口定义:

public interface ApplicationContextAware {

    void setApplicationContext(ApplicationContext applicationContext) throws BeansException;
}

应用场景:参考https://www.cnblogs.com/cg961107/p/11225325.html

官方不推荐使用

(2)BeanNameAware

用途:

在spring对实现该接口的bean初始化时调用该方法,name为bean的名称

接口定义:

public interface BeanNameAware {
    void setBeanName(String name) throws BeansException;
}

应用实例:

  

@Service
public  class IndexServiceImpl implements IndexService,BeanNameAware {
    @Autowired
    private IndexDao indexDao;

    @Override
    public void get() {
        indexDao.get();

    }
    @Override
    public void setBeanName(String name) {
        System.out.println("bean的名字为-->"+name);

    }
}

console:

  

bean的名字为-->indexServiceImpl

3.基于注释的spring配置

1.@Configuration:表示该类为spring的初始化类---->applicationContext.xml

 @bean------><bean id="methodName" Class="方法返回值"></bean>

@Configuration
public class MovieConfiguration {

    @Bean
    public MovieCatalog firstMovieCatalog() { ... }

    @Bean
    public MovieCatalog secondMovieCatalog() { ... }

    // ...
}

2.@primary---->表示当多个bean可以自动装配到单值依赖项时,应该优先选择特定的bean。

使用场景:当我通过AnnotationConfigApplicationContext.getBean一般通过两种形式,byName,byType

当时通过byType时,程序会抛异常,因为两个MovieCatalog,name可以通过@primary去指定优先选择哪个Bean

 @Bean
    @Primary
    public MovieCatalog firstMovieCatalog() { ... }

xml方式则为:

    <bean class="example.SimpleMovieCatalog" primary="true">
        <!-- inject any dependencies required by this bean -->
    </bean>

 

3.@Qualifier

  上文已经总结.

4.Environment Abstraction 环境抽象

两种声明方式

@Configuration
@Profile("development")
public class StandaloneDataConfig {

    @Bean
    public DataSource dataSource() {
        return new EmbeddedDatabaseBuilder()
            .setType(EmbeddedDatabaseType.HSQL)
            .addScript("classpath:com/bank/config/sql/schema.sql")
            .addScript("classpath:com/bank/config/sql/test-data.sql")
            .build();
    }
}

配置类中的方法:

@Configuration
public class AppConfig {

    @Bean("dataSource")
    @Profile("development") 
    public DataSource standaloneDataSource() {
        return new EmbeddedDatabaseBuilder()
            .setType(EmbeddedDatabaseType.HSQL)
            .addScript("classpath:com/bank/config/sql/schema.sql")
            .addScript("classpath:com/bank/config/sql/test-data.sql")
            .build();
    }

    @Bean("dataSource")
    @Profile("production") 
    public DataSource jndiDataSource() throws Exception {
        Context ctx = new InitialContext();
        return (DataSource) ctx.lookup("java:comp/env/jdbc/datasource");
    }
}

作用:比如说,我们有两个数据源,一个用于生产,一个用于测试,那么我可以通过@Profile声明其所在环境,使spring去加载指定的bean,那么如何使用呢

举例:

配置类:

一个生产,一个测试

@Configuration
@ComponentScan("cn.cg.*")
public class AppConfig {
    @Bean
    @Profile("test")
    public Person person1(){
        Person p = new Person();
        p.setName("张三");
        return p;
    }
    @Bean()
    @Profile("produce")
    public Person person2(){
        Person p = new Person();
        p.setName("李四");
        return p;
    }


}

test:

public class mainClass {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext();
        //设置环境抽象
        ac.getEnvironment().setActiveProfiles("produce");
        //注册appConfig
        ac.register(AppConfig.class);
        //刷新容器
        ac.refresh();
        //获取 person->李四
        Person person = ac.getBean(Person.class);
        System.out.println(person.getName());
    }
}

console:李四

 

posted @ 2019-07-24 02:11  简单爱1  阅读(141)  评论(0编辑  收藏  举报