Spring笔记之IOC

折月煮酒 提交于 2020-01-20 01:08:43

本篇笔记忽略jar包的导入和配置文件的schema约束
1.我理解的IOC
ioc,控制反转,在spring中我理解的ioc就是将需要创建的对象交由spring来创建。在spring中,可以通过配置,来让spring通过反射创建对象并放到spring容器中。这样,其他地方需要调用时,只需要通过配置的id属性来获取即可使用。
配置可以配置具体实现类,也可以配置包,包下所有类的id默认为类名首字母小写。
<bean id="testService" class="com.jdwa.service.impl.TestServiceImpl"></bean>
2.ioc中创建bean的三种方式
默认构造:<bean id="testService" class="com.jdwa.service.impl.TestServiceImpl"></bean>
静态工厂:<bean id="testService" class="com.jdwa.factory.StaticFactory" factory-method="createTestService"></bean>
实例工厂:
<bean id="instancFactory" class="com.jdwa.factory.InstanceFactory"></bean>
<bean id="testService" factory-bean="instancFactory" factory-method="createTestService"></bean>

3.bean的生命周期
单例:应用加载时创建容器时创建,卸载时销毁;
多例:与普通对象同,即使用时创建,由垃圾回收机制销毁回收

4.依赖注入(Dependency Injection)
依赖注入是spring框架核心ioc的具体实现。
我们在编写代码时,对象的创建已经交由spring,但是代码中不可能出现没有依赖的情况。ioc解耦,只是降低依赖,并不能消除。
针对具体情况,比如我们需要将持久层注入到业务层。
简单来说,就是我们坐等框架把对象注入进来,不用我们自己去获取。
依赖注入常见的三个方法:
构造注入,set方法注入,p名称空间注入(实质还是set方法注入)

5.基于注解的ioc
首先,使用注解要有一个认知,注解配置和 xml 配置要实现的功能都是一样 的,都是要降低程序间的耦合。只是配置的形式不一样。

常用注解,替代的xml,以及作用
|注解| 替代的xml | 作用 |
|:-: | :-: | :-: |
|@Component | | 把资源让 spring 来管理|
|@Controller | | @Component 的衍生注解,一般用于表现层|
|@Service | | @Component 的衍生注解,一般用于业务层|
|@Repository | | @Component 的衍生注解,一般用于持久层|
|@Autowired | <property name="" value=">或| 自动按照类型注入|
|@Qualifier | /|在按照类型注入基础上,按照名称注入。给字段注入不能单独使用,必须和@Autowired一起使用。在给方法参数使用时可以单独使用|
|@Resource |/| 直接按照 Bean 的 id 注入。它也只能注入其他 bean 类型|
|@Value | /| 注入基本数据类型和 String 类型数据的|
|@Scope | | 指定 bean 的作用范围|
|@PostConstruct | | 指定初始化方法|
|@PreDestroy | |指定销毁方法 |

6.基于注解之后待改造的问题
也就是想完全基于注解开发,去除xml还需要解决的问题
一个是告知容器读取配置文件,一个是第三方资源需要xml配置

<!-- 告知spring框架在,读取配置文件,创建容器时,扫描注解,依据注解创建对象,并存入容器中 --> 
<context:component-scan base-package="com.jdwa"></context:component-scan>
<!-- 配置 dbAssit -->
<bean id="dbAssit" class="com.itheima.dbassit.DBAssit"> 
    <property name="dataSource" ref="dataSource"></property> 
 </bean>   
 <!-- 配置数据源 --> 
 <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> 
    <property name="driverClass" value="com.mysql.jdbc.Driver"></property>   
    <property name="jdbcUrl" value="jdbc:mysql:///spring_day02"></property>   
    <property name="user" value="root"></property>  
    <property name="password" value="1234"></property> 
 </bean>

解决步骤如下:
第一步:

@Configuration
public class SpringConfiguration {
 }

@Configuration注解用于指定当前类是一个 spring 配置类,当创建容器时会从该类上加载注解。获取容器时需要使用 AnnotationApplicationContext(有@Configuration 注解的类.class)。

第二步:

@Configuration 
@ComponentScan("com.jdwa") 
public class SpringConfiguration { 
} 

@ComponentScan用于指定 spring 在初始化容器时要扫描的包。作用和在 spring 的 xml 配置文件中的: 是一样的。

第三步:

public class JdbcConfig {
   
    @Bean(name="runner")
    @Scope("prototype")
    public QueryRunner createQueryRunner(@Qualifier("ds2") DataSource dataSource){
        return new QueryRunner(dataSource);
    }

  
    @Bean(name="ds2")
    public DataSource createDataSource(){
        try {
            ComboPooledDataSource ds = new ComboPooledDataSource();
            ds.setDriverClass(driver);
            ds.setJdbcUrl(url);
            ds.setUser(username);
            ds.setPassword(password);
            return ds;
        }catch (Exception e){
            throw new RuntimeException(e);
        }
    }

    @Bean(name="ds1")
    public DataSource createDataSource1(){
        try {
            ComboPooledDataSource ds = new ComboPooledDataSource();
            ds.setDriverClass(driver);
            ds.setJdbcUrl("jdbc:mysql://localhost:3306/eesy02");
            ds.setUser(username);
            ds.setPassword(password);
            return ds;
        }catch (Exception e){
            throw new RuntimeException(e);
        }
    }
}

@Bean注解只能写在方法上,表明使用此方法创建一个对象,并且放入 spring 容器。

第四步:

@PropertySource("classpath:jdbcConfig.properties")
public class JdbcConfig {

    @Value("${jdbc.driver}")
    private String driver;

    @Value("${jdbc.url}")
    private String url;

    @Value("${jdbc.username}")
    private String username;

    @Value("${jdbc.password}")
    private String password;

    /**
     * 用于创建一个QueryRunner对象
     * @param dataSource
     * @return
     */
    @Bean(name="runner")
    @Scope("prototype")
    public QueryRunner createQueryRunner(@Qualifier("ds2") DataSource dataSource){
        return new QueryRunner(dataSource);
    }

    /**
     * 创建数据源对象
     * @return
     */
    @Bean(name="ds2")
    public DataSource createDataSource(){
        try {
            ComboPooledDataSource ds = new ComboPooledDataSource();
            ds.setDriverClass(driver);
            ds.setJdbcUrl(url);
            ds.setUser(username);
            ds.setPassword(password);
            return ds;
        }catch (Exception e){
            throw new RuntimeException(e);
        }
    }

    @Bean(name="ds1")
    public DataSource createDataSource1(){
        try {
            ComboPooledDataSource ds = new ComboPooledDataSource();
            ds.setDriverClass(driver);
            ds.setJdbcUrl("jdbc:mysql://localhost:3306/eesy02");
            ds.setUser(username);
            ds.setPassword(password);
            return ds;
        }catch (Exception e){
            throw new RuntimeException(e);
        }
    }
}

@PropertySource用于加载.properties 文件中的配置。例如我们配置数据源时,可以把连接数据库的信息写到 properties 配置文件中,就可以使用此注解指定 properties 配置文件的位置。

第五步:

@ComponentScan("com.itheima")
@Import(JdbcConfig.class)
@PropertySource("classpath:jdbcConfig.properties")
public class SpringConfiguration {


}

@Import用于导入其他配置类,在引入其他配置类时,可以不用再写@Configuration 注解。当然,写上也没问 题

第六步:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfiguration.class)
public class AccountServiceTest {}

ApplicationContext ac =     new AnnotationConfigApplicationContext(SpringConfiguration.class); 

@ContextConfiguration(locations= {"classpath:bean.xml"}) 是加载配置文件,上面代码则是加载配置类

更有早行人.jpg

     ------莫道君行早,更有早行人------
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!