Spring简介与入门02

第2章基于注解的IOC配置

1.1        环境搭建

1.1.1     第一步:拷贝必备jar包到工程的lib目录。

                   注意:在基于注解的配置中,我们还要多拷贝一个aop的jar包。如下图:   

1.1.2      第二步:在类的根路径下创建一个任意名称的xml文件(不能是中文)

         基于注解整合时,导入约束时需要多导入一个context名称空间下的约束。

给配置文件导入约束:

<?xml version="1.0"encoding="UTF-8"?>

<!--导入schema

约束的位置在:

    ..\spring-framework-4.2.4.RELEASE\docs\spring-framework-reference\html\xsd-configuration.html

    文件中。

注意:要导入schema约束

-->

<beansxmlns="http://www.springframework.org/schema/beans"

      xmlns:context="http://www.springframework.org/schema/context"

       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

                http://www.springframework.org/schema/context

                 http://www.springframework.org/schema/context/spring-context.xsd ">

</beans>

1.1.3      第三步:使用@Component注解配置管理的资源

/**

  * 客户的业务层实现类

  */

@Component(value="customerService")

public class CustomerServiceImplimplements ICustomerService {

    @Override

    public void saveCustomer() {

        System.out.println("执行了保存客户");

    }

}

1.1.4      第四步在spring的配置文件中开启spring对注解ioc的支持

<!-- 告知spring框架在,读取配置文件,创建容器时,扫描注解,依据注解创建对象,并存入容器中 -->

        <context:component-scanbase-package="com.itheima"></context:component-scan>

1.2        常用注解

1.2.1     用于创建对象的

      相当于:<bean id="" class="">

1.2.1.1  @Component

  作用:

               把资源让spring来管理。相当于在xml中配置一个bean。

属性:

                value:指定bean的id。如果不指定value属性,默认bean的id是当前类的类名。首字母小写。         

1.2.1.2   @Controller  @Service  @Repository

                   他们三个注解都是针对一个的衍生注解,他们的作用及属性都是一模一样的。

                   他们只不过是提供了更加明确的语义化。

                            @Controller一般用于表现层的注解。

                            @Service一般用于业务层的注解。

                            @Repository一般用于持久层的注解。

                   细节:如果注解中有且只有一个属性要赋值时,且名称是valuevalue在赋值时可以不写。

1.2.2     用于注入数据的

       相当于:<property name="" ref="">       <propertyname="" value="">

1.2.2.1  @Autowired

                   作用:

                    自动按照类型注入。当使用注解注入属性时,set方法可以省略。它只能注入其他bean类型。当有多个类型匹配时,使用要注入的对象变量名称作为bean的id,在spring容器查找,找到了也可以注入成功。找不到就报错。

1.2.2.2  @Qualifier

                   作用:

                      在自动按照类型注入的基础之上,再按照Bean的id注入。它不能独立使用,必须和@Autowire一起使用。

                   属性:

                            value:指定bean的id。

1.2.2.3  @Resource

                   作用:

                     直接按照Bean的id注入。它也只能注入其他bean类型。

                  属性:

                            name:指定bean的id。

1.2.2.4  @Value

                   作用:

                            注入基本数据类型和String类型数据的

                   属性:

                            value:用于指定值

1.2.3     用于改变作用范围的:

         相当于:<bean id="" class=""scope="">

1.2.3.1  @Scope

                   作用:

                            指定bean的作用范围。

                   属性:

                            value:指定范围的值。

                            取值:singleton  prototype requestsession globalsession

1.2.4     和生命周期相关的:(了解) 

         相当于:<bean id="" class=""init-method=""destroy-method="" />

1.2.4.1  @PostConstruct

                   作用:

                            用于指定初始化方法。

1.2.4.2  @PreDestroy

                   作用:

                            用于指定销毁方法。

1.2.5      代码示例

业务层代码:

/**

  * 客户的业务层接口

  * @authorzhy

  */

public interface ICustomerService {   

    /**

      * 保存客户

      * @param customer

      */

    void saveCustomer();  

} 

/**

  * 客户的业务层实现类

  * @authorzhy

*/

//作用就相当于在xml中配置了一个bean标签,该注解有value属性,含义是beanid

//不写的时候,默认的id是:当前类名,且首字母小写。即:customerServiceImpl

@Component(value="customerService")

@Scope(value="singleton")

public class CustomerServiceImplimplements ICustomerService {

// 自动按照数据类型注入,拿着当前变量的数据类型在spring的容器中找,找到后,给变量赋值。

//  当有多个类型匹配时,会使用当前变量名称customerDao作为beanid,继续在容器中找。

//  找到了,也能注入成功。找不到就报错。

//  @Autowired

//  @Qualifier(value="customerDao2")//在自动按照类型注入的基础之上,再按照id注入

    @Resource(name="customerDao2")//直接按照beanid注入

    private ICustomerDaocustomerDao =null;   

    @Value("com.mysql.jdbc.Driver")//注入基本类型和String类型数据

    private Stringdriver; 

@Override

    public void saveCustomer() {

        System.out.println(driver);

        customerDao.saveCustomer();

    }

} 

持久层代码:

/**

  * 客户的持久层接口

  * @authorzhy

  */

public interface ICustomerDao {

    /**

      * 保存客户

      */

    void saveCustomer();

}

/**

  * 客户的持久层实现类11111111111111111111

  * @authorzhy

*/

@Repository("customerDao1")

public class CustomerDaoImplimplements ICustomerDao { 

    @Override

    public void saveCustomer() {

        System.out.println("保存了客户111111111111111111");

    }

}

/**

  * 客户的持久层实现类222222222222222222222222

  * @authorzhy

*/

@Repository("customerDao2")

public class CustomerDaoImpl2implements ICustomerDao {

@Override

    public void saveCustomer() {

        System.out.println("保存了客户2222222222222222222");

    }

} 

测试类代码:

publicclass Client {

    public static void main(String[] args) {

        //1.获取容器

        ApplicationContext ac =newClassPathXmlApplicationContext("bean.xml");

        //2.根据id获取对象

        ICustomerService cs = (ICustomerService)ac.getBean("customerService");              cs.saveCustomer();

    }

}

配置文件:

<?xml version="1.0"encoding="UTF-8"?>

<!--我们导入约束时,除了昨天的那部分之外,还要单独导入一个context名称空间 -->

<beansxmlns="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框架在通过读取配置文件创建容器时,扫描的包,并根据包中类的注解创建对象-->

    <context:component-scanbase-package="com.itheima"></context:component-scan>

</beans>

1.2.6     关于注解和XML的选择问题

         注解的优势:

          配置简单,维护方便(我们找到类,就相当于找到了对应的配置)。

         XML的优势:

          修改时,不用改源码。不涉及重新编译和部署。

1.3        spring管理对象细节

         基于注解的spring IoC配置中,bean对象的特点和基于XML配置是一模一样的。

         写到此处,基于注解的IoC配置已经完成,但是大家都发现了一个问题:我们依然离不开spring的xml配置文件,那么能不能不写这个bean.xml,所有配置都用注解来实现呢?

         答案是肯定的,请看下一章节。

1.4        spring的纯注解配置

1.4.1      待改造的问题

我们发现,之所以我们现在离不开xml配置文件,是因为我们有一句很关键的配置:

<!-- 告知spring框架在读取配置文件,创建容器时,扫描注解,依据注解创建对象,并存入容器中 -->

    <context:component-scanbase-package="com.itheima"></context:component-scan>

如果它要也能用注解配置,那么我们就可以脱离xml文件了。

1.4.2      使用注解配置要扫描的包

如果不使用xml对bean进行管理。那么,那句关键的配置跑哪去了呢?

在service的实现类上:

/**

  * 客户的业务层实现类

  * @authorzhy

  */

@Configuration//表明当前类是一个配置类

@ComponentScan(basePackages ="com.itheima")//配置要扫描的包

//以上两个注解可以写在业务层上,可以单独创建一个类,然后写在类上。

@Component//作用就相当于在xml中配置了一个bean标签,该注解有value属性,含义是beanid。不写的时候,默认的id是:customerServiceImpl

@Scope(value="singleton")

public class CustomerServiceImplimplements ICustomerService {

   

//  @Autowired//自动按照数据类型注入,拿着当前变量的数据类型在spring的容器中找,找到后,给变量赋值。

//  @Qualifier(value="customerDao2")//在自动按照类型注入的基础之上,再按照id注入

    @Resource(name="customerDao2")//直接按照beanid注入

    private ICustomerDaocustomerDao =null;   

    @Value("com.mysql.jdbc.Driver")

    private Stringdriver;

    @Override

    public void saveCustomer() {

        System.out.println(driver);

        customerDao.saveCustomer();

    }

} 

那么新的问题又来了,我们如何获取容器呢?

public class Client {

    public static void main(String[] args) {

        //1.获取容器:由于我们已经没有了xml文件,所以再用读取xml方式就不能用了。

        //需要指定加载哪个类上的注解

        ApplicationContext ac =

            new AnnotationConfigApplicationContext(CustomerServiceImpl.class);

        //2.根据id获取对象

        ICustomerService cs = (ICustomerService)ac.getBean("customerService");

        cs.saveCustomer();

    }

}

1.4.3      新注解说明

1.4.3.1   @Configuration

         作用:

                   用于指定当前类是一个配置类,会从该类上加载注解。读取该类上@ ComponentScan注解初始化spring容器。

1.4.3.2   @ComponentScan

         作用:

                   用于指定spring在初始化容器时要扫描的包。

         属性

                   basePackages:用于指定要扫描的包。和该注解中的value属性作用一样。

1.4.3.3   @PrppertySource

         作用:用于加载.properties文件中的配置

         属性:

                   value[]:用于指定properties文件位置。如果是在类路径下,需要写上classpath:

         示例代码:

配置:

@Configuration

@ComponentScan(basePackages ="cn.itcast.spring")

@PropertySource("classpath:info.properties")

public class Configuration_A {

} 

实体类:

@Component("car")

public class Car {

    private Stringid ;

    @Value("${car.name}")//此时是读取properties文件,根据keyvalue了。

    private Stringname ;

    @Value("${car.price}")//此时是读取properties文件,根据keyvalue了。

    private Doubleprice ;

    public String getId() {

        return id;

    }

    public void setId(Stringid) {

        this.id =id;

    }

    public String getName() {

        return name;

    }

    public void setName(Stringname) {

        this.name =name;

    }

    public Double getPrice() {

        returnprice;

    }

    public void setPrice(Doubleprice) {

        this.price =price;

    }

    @Override

    public String toString() {

        return"Car [id=" +id + ", name=" +name +", price=" +price + "]";

    }

}

info.properties文件:

car.name= \u4FDD\u65F6\u6377//中文是保时捷

car.price= 1000000

1.4.3.4   @Import

         作用:

                   用于导入其他配置类

         属性:

                   value[]:用于指定其他配置类的字节码。

         示例代码:

@Configuration

@ComponentScan(basePackages ="cn.itcast.spring")

@Import({ Configuration_B.class})

public class Configuration_A {

}

@Configuration

@PropertySource("classpath:info.properties")

public class Configuration_B {

  }

1.4.3.5   @Bean

         作用:

                   该注解只能写在方法上,表明使用此方法创建一个对象,并且交给spring管理。

      属性:

           name给当前@Bean注解方法创建的对象指定一个名称(beanid)。

      示例代码:

@Bean(name ="datasource2")

    public DataSource createDS()throwsException {

        ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();

        comboPooledDataSource.setUser("root");

        comboPooledDataSource.setPassword("1234");

        comboPooledDataSource.setDriverClass("com.mysql.jdbc.Driver");

        comboPooledDataSource.setJdbcUrl("jdbc:mysql:///spring_ioc");

        return comboPooledDataSource;

    }

第2章  Spring整合Junit

2.1        准备测试环境

2.1.1      创建业务层接口实现类

/**

  * 客户的业务层接口

  * @authorzhy

  */

public interface ICustomerService {

      /**

      * 查询所有客户

      * @return

      */

    List<Customer> findAllCustomer();

       /**

      * 保存客户

      * @param customer

      */

    void saveCustomer(Customercustomer);

}

/**

  * 客户的业务层实现类

  * @authorzhy

 */

publicclass CustomerServiceImplimplementsICustomerService {

    private ICustomerDaocustomerDao;

      public void setCustomerDao(ICustomerDaocustomerDao) {

        this.customerDao =customerDao;

    }

    @Override

    public List<Customer> findAllCustomer() {

        returncustomerDao.findAllCustomer();

    }

    @Override

    public void saveCustomer(Customercustomer) {

        customerDao.save(customer);

    }

}

2.1.2      创建持久层接口实现类

/**

  * 客户的持久层接口

  * @authorzhy

  */

public interface ICustomerDao {   

    /**

      * 查询所有客户

      * @return

    */

    List<Customer> findAllCustomer();

    /**

      * 保存客户

      * @param customer

      */

    void save(Customercustomer);

} 

/**

  * 客户的持久层实现类

  * @authorzhy

  */

public class CustomerDaoImplimplements ICustomerDao {

    @Override

    public List<Customer>findAllCustomer() {

        System.out.println("查询了所有客户");

        return null;

    } 

    @Override

    public void save(Customercustomer) {

        System.out.println("保存了客户");

    }

}

2.1.3      导入junit的jar包

2.1.4      编写测试类

/**

  * 测试客户的业务层和持久层

  * @authorzhy

  */

public class CustomerServiceTest { 

    private ICustomerServicecustomerService;   

    @Test

    public void testFindAll(){

        customerService.findAllCustomer();

    }   

    @Test

    public void testSave(){

        Customerc =new Customer();

        c.setCustName("传智学院 "); 

        customerService.saveCustomer(c);

    }

}

2.2        使用xml配置步骤

2.2.1      xml文件中的配置

<?xml version="1.0"encoding="UTF-8"?>

<beansxmlns="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">

    <!--把资源交给spring来管理 -->

    <beanid="customerDao"class="com.itheima.dao.impl.CustomerDaoImpl"></bean>   

    <beanid="customerService"class="com.itheima.service.impl.CustomerServiceImpl">

        <propertyname="customerDao"ref="customerDao"></property>

    </bean>

</beans>

2.2.2      第一步:拷贝整合junit的必备jar包到lib目录

此处需要注意的是,导入jar包时,需要导入一个spring中aop的jar包。

2.2.3      第二步:使用@RunWith注解替换原有运行器

@RunWith(SpringJUnit4ClassRunner.class)

public class CustomerServiceTest {   

    private ICustomerServicecustomerService;   

    @Test

    public void testFindAll(){

        customerService.findAllCustomer();

    }   

    @Test

    public void testSave(){

        Customerc =new Customer();

        c.setCustName("传智学院 "); 

        customerService.saveCustomer(c);

    }

} 

2.2.4      第三步:使用@ContextConfiguration指定spring配置文件的位置

@RunWith(SpringJUnit4ClassRunner.class)

@ContextConfiguration(locations={"classpath:bean.xml"})

publicclassCustomerServiceTest {

    privateICustomerServicecustomerService;   

    @Test

    public voidtestFindAll(){

        customerService.findAllCustomer();

    }   

    @Test

    public void testSave(){

        Customer c = newCustomer();

        c.setCustName("传智学院 "); 

        customerService.saveCustomer(c);

    }

}

2.2.5      第四步:使用@Autowired给测试类中的变量注入数据

@RunWith(SpringJUnit4ClassRunner.class)

@ContextConfiguration(locations={"classpath:bean.xml"})

publicclass CustomerServiceTest { 

    @Autowired

    private ICustomerServicecustomerService;   

    @Test

    public voidtestFindAll(){

        customerService.findAllCustomer();

    }   

    @Test

    public void testSave(){

        Customer c = newCustomer();

        c.setCustName("传智学院 "); 

        customerService.saveCustomer(c);

    }

}

2.3        使用纯注解配置步骤

2.3.1      第一步:拷贝整合junit的必备jar包到lib目录

此处需要注意的是,导入jar包时,需要导入一个spring中aop的jar包。

2.3.2      第二步:把资源都用注解管理

@Service("customerService")

public class CustomerServiceImplimplements ICustomerService { 

    @Autowired

    private ICustomerDaocustomerDao; 

    @Override

    public List<Customer>findAllCustomer() {

        returncustomerDao.findAllCustomer();

    } 

    @Override

    public void saveCustomer(Customer customer) {

        customerDao.save(customer);

    }

} 

/**

  * 客户的持久层实现类

  * @authorzhy

  */

@Repository("customerDao")

public class CustomerDaoImplimplements ICustomerDao { 

    @Override

    public List<Customer>findAllCustomer() {

        System.out.println("查询了所有客户");

        return null;

    } 

    @Override

    public void save(Customer customer) {

        System.out.println("保存了客户");

    }

}

2.3.3      第三步:使用注解配置方式创建spring容器

@Configuration

@ComponentScan(basePackages={"com.itheima"})

publicclass CustomerServiceTest { 

    @Autowired

    private ICustomerServicecustomerService;   

    @Test

    public void testFindAll(){

        customerService.findAllCustomer();

    }   

    @Test

    public void testSave(){

        Customer c =new Customer();

        c.setCustName("传智学院 "); 

        customerService.saveCustomer(c);

    }

}

2.3.4     第四步:使用RunWith注解和ContextConfiguration注解配置

@RunWith(SpringJUnit4ClassRunner.class)

@ContextConfiguration(classes={CustomerServiceTest.class})

@Configuration

@ComponentScan(basePackages={"com.itheima"})

publicclass CustomerServiceTest { 

    @Autowired

    private ICustomerServicecustomerService;   

    @Test

    public void testFindAll(){

        customerService.findAllCustomer();

    }   

    @Test

    public void testSave(){

        Customer c = newCustomer();

        c.setCustName("传智学院 "); 

        customerService.saveCustomer(c);

    }

}

 

2.4        为什么不把测试类配到xml中

在解释这个问题之前,先解除大家的疑虑,配到XML中能不能用呢?

答案是肯定的,没问题,可以使用。

那么为什么不采用配置到xml中的方式呢?

这个原因是这样的:

         第一:当我们在xml中配置了一个bean,spring加载配置文件创建容器时,就会创建对象。

         第二:测试类只是我们在测试功能时使用,而在项目中它并不参与程序逻辑,也不会解决需求上的问题,所以创建完了,并没有使用。那么存在容器中就会造成资源的浪费。

         所以,基于以上两点,我们不应该把测试配置到xml文件中。

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值