美文网首页
04-Spring-注解的IOC和DI

04-Spring-注解的IOC和DI

作者: XAbo | 来源:发表于2020-12-30 12:55 被阅读0次

    **Spring总结:1.通过IOC容器管理Bean。 2.通过DI管理Bean的属性。 **

    一、 基本的用法

    配置文件:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context.xsd">
    
        <!--告知Spring Bean的创建配置在类中  新增context命名空间   -->
      <context:component-scan base-package="com.annotation"></context:component-scan>
    
    </beans>
    

    AccountServicesImpl:

    /*  
     XML的配置
    <bean id="accountServices" class="com.annotation.services.AccountServicesImpl" scope="" init-method="" destory-method="">
        <property name="" value=""></property>
        <property name="" ref=""> </property>
    </bean>
    --1 xml实现的功能:
    
     1.用于管理对象:1.1 bean标签创建对象; 1.2 init-method destory-method;管理bean的生命周期 ; 1.3 scope:管理bean的作用范围。
     2.用于注入数据:property。
    
    --2 注解实现的功能:
    
     1.用于管理对象:
         1.1 @Component创建对象,将当前对象存入IOC容器 ,其属性value用于指定bean的id,默认是当前类名(首字母小写)。
         1.2 @Controller:表现层  @Service:业务/服务层  @Repository:持久层 这三个注解的作用和属性跟@Component一样。
     2.用于注入数据的(JavaBean类型)
        2.1 @Autowired:按照类型注入,Bean对象类型和要注入的变量类型匹配。
           2.1.1 注入不依赖构造方法或set方法,Spring直接在IOC容器中找到“合适”的一个对象,将其属性注入。
           2.1.2 当IOC容器中有多个匹配到的话,在根据变量名称进行匹配。
        2.2 @Qualifier:按照类型基础之上再按照名称注入,value属性指定Bean的ID。
          2.2.1 给类成员注入时不能单独使用,需要跟Autowired配合使用。
          2.2.2 给方法参数注入时可以。
        2.3 @Resource:直接按照Bean的id注入,可独立使用。使用name来指定Bean的id。
     3. 用于注入数据的(基本和String类型)
        3.1 @Value:使用value属性指定要注入的值,可使用spEL。${表达式}
     4. 用于注入数据的:集合类型的属性只能通过XML进行注入。
     5. 管理Bean的作用范围:@Scope指定bean的作用范围,属性value指定范围的取值。
     6. 管理Bean的生命周期:@PreDestory :用于指定销毁方法。 @PostConstruct :用于指定初始化方法。
    
     补充:@Autowired注解位置:
       1.放置在对应成员变量的set方法上.[弱依赖,可有可无,不影响整个类]
       2.放置在成员变量上,Spring通过反射直接对成员变量进行注入(推荐)[有缺点,idea还会警告:不建议使用这种方式注入]
       3.放在构造器上[强制依赖]
     */
    @Component(value = "accountServices")
    public class AccountServicesImpl implements AccountServices {
    
         //@Autowired
         @Resource
        private AccountDao accountDao;
    
        public void saveAccount() {
             accountDao.saveAccount();
        }
    }
    
    
    注解的Autowired方式

    AccountDaoImpl:

    @Repository("accountDao")
    public class AccountDaoImpl implements AccountDao {
        @Override
        public void saveAccount() {
            System.out.println("DAO---保存账户数据");
        }
    }
    

    客户端:

    public class client {
        public static void main(String[] args) {
            ClassPathXmlApplicationContext  ApplicationContext = new ClassPathXmlApplicationContext("bean.xml");
            AccountServices accountServices = (AccountServices) ApplicationContext.getBean("accountServices");
            accountServices.saveAccount();
        }
    }
    

    二、依赖第三方jar

    1.当依赖第三方jar包的时候,不能使用注解的时候,如何去掉剩余标签?

    <?xml version="1.0" encoding="UTF-8"?>
    <!--
    两部分: 1.根标签beans的别名:xmlns="http://www.springframework.org/schema/beans"
           2.约束文件:schemaLocation引入约束,然后给约束地址起个别名xsi
      -->
    
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context.xsd">
    
        <!--告知Spring Bean的创建配置在类中  新增context命名空间   -->
      <context:component-scan base-package="com.annotation"></context:component-scan>
     <!--这些bean不能使用注解写在源码上-->
     <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSourrce">
         <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
         <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/mydb"></property>
         <property name="user" value="root"></property>
         <property name="password"  value="213"></property>
     </bean>
     <bean id="runner" class="org.apache.commons.dbutils.QueryRunner" scope="prototype">
        <constructor-arg name="ds" ref="dataSource"></constructor-arg>
     </bean>
    
    </beans>
    

    2.使用新注解解决bean配置文件中遗留的便签。
    使用SpringConfig类:

    /*
    * @Configuration:指定当前类是一个配置类.
    * @ComponentScan:通过注解指定spring在创建容器时候要扫码的包。等同于:<context:component-scan base-package="com.annotation"></context:component-scan>
    * @Bean:把当前方法的返回值放入SpringIOC容器中。属性:name指定bean的id,默认是当前方法名。其装配bean的方式与@Autowired相似。
      @PropertySource指定加载的properties配置文件。classpath表示类路径。
    * */
    @Configuration
    @ComponentScan(basePackages = "com.annotation")
    //@Import("otherConfig.class")  可导入其他配置子类。 
    /*@Import相当于xml文件中的
     * <import resource="classpath*:/spring/job-timer.xml" />
     */
    @PropertySource("classpath:db.properties")
    public class SpringConfig {
     @Valure("$jdbc.driver")
     private String driver;
     @Valure("$jdbc.url")
     private String url;
     @Valure("$jdbc.user")
     private String user;
     @Valure("$jdbc.pwd")
     private String passWrod ;
    
    @Bean(name="dataSource")
    public DataSource createDataSource(){
        ComboPooledDataSourrce ds = new ComboPooledDataSourrce()
        //ds.setDriverClass("com.mysql.jdbc.Driver");
        //ds.setJdbcUrl("jdbc:mysql://localhost:3306/mydb");
        //ds.setUser("root");
        //ds.setPassword("123");
        ds.setDriverClass(driver);
        ds.setJdbcUrl(url);
        ds.setUser(user);
        ds.setPassword(passWrod);
        return ds;
    }
    @Bean(name="runner")
    @Scope("prototype")
    public QueryRunner createQueryRunner(DataSource dataSource){
        return  new QueryRunner(dataSource);
    }
    }
    

    用到的db.properties配置文件

    #mysql jdbc
    jdbc.driver=com.mysql.jdbc.Driver
    jdbc.url=jdbc:mysql://localhost:3306/mydb
    jdbc.user=root
    jdbc.pwd=123
    

    3.此时不需要bean配置文件。

    三、集成junit

    1.传统的测试用例

    import com.annotation.services.AccountServices;
    import org.junit.Test;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class AccountServiceTest {
        @Test
        public void testFindAll() {
            ClassPathXmlApplicationContext ApplicationContext = new ClassPathXmlApplicationContext("bean.xml");
            AccountServices accountServices = (AccountServices) ApplicationContext.getBean("accountServices");
            List<Account> accounts = accountServices.findAll();
            for (Account account : accounts) {
                System.out.println(account);
            }
        }
    
        @Test
        public void testFindOne() {
            ClassPathXmlApplicationContext ApplicationContext = new ClassPathXmlApplicationContext("bean.xml");
            AccountServices accountServices = (AccountServices) ApplicationContext.getBean("accountServices");
            Account accounts = accountServices.findOne("xzb");
            System.out.println(account);
    
        }
    }
    

    2.Spring集成junit

    import com.annotation.services.AccountServices;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    
    /*
    * Spring整合junit
    * 1.导入spring整合junit的jar
    * 2.@RunWith,使用junit提供一个注解把原有的main方法替代了,换成spring提供的。
    * 3.@ContextConfiguration 告知spring的运行器,spring的IOC容器创建是xml还是注解。Spring 5.x <---> junit 4.12+
    *   location:指定XML文件的位置,加上classpath,表示在类路径下。
    *   classes:指定注解所在位置。
    */
    
    @RunWith(SpringJUnit4ClassRunner.class)//指定main
    @ContextConfiguration(SpringConfig.class)//获取Sping IOC容器
    //@ContextConfiguration(locations= {"classpath:bean.xml"})
    public class AccountServiceTest {
        @Autowired
        private AccountServices accountServices  = null;
        @Test
        public void testFindAll() {
            List<Account> accounts = accountServices.findAll();
            for (Account account : accounts) {
                System.out.println(account);
            }
        }
    
        @Test
        public void testFindOne() {
            Account accounts = accountServices.findOne("xzb");
            System.out.println(account);
    
        }
    }
    

    junit为什么不采用配置到 xml 中的方式呢?
    第一:当我们在 xml 中配置了一个 bean, spring 加载配置文件创建容器时,就会创建对象。
    第二:测试类只是我们在测试功能时使用,而在项目中它并不参与程序逻辑,也不会解决需求上的问
    题,所以创建完了,并没有使用。那么存在容器中就会造成资源的浪费。

    相关文章

      网友评论

          本文标题:04-Spring-注解的IOC和DI

          本文链接:https://www.haomeiwen.com/subject/lqdinktx.html