spring学习笔记 -- day04 基于注解的配置

来源:互联网 发布:思科路由端口转换 编辑:程序博客网 时间:2024/06/05 21:11

一、环境搭建

1、创建web项目导入jar包

注意:基于注解的配置需要导入aop的支持包:spring-aop-4.2.4.RELEASE.jar



2、创建spring配置文件

<?xml version="1.0" encoding="UTF-8"?><!-- 导入约束:除了要导入第一天的约束之外,还要导入context的名称空间和约束--><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"></beans>

3、使用@Component注解配置管理的资源

@Component

        它就相当于在配置文件中配置了一个bean标签。

        value属性用于指定bean的id

        如果没有指定value属性,bean的id就是当前类的名称,首字母改小写。

import org.springframework.stereotype.Controller;import org.springframework.stereotype.Repository;import cn.itcast.dao.ICustomerDao;/** * 客户的持久层实现类 * * <bean id="customerDao" class="cn.itcast.dao.impl.CustomerDaoImpl"></bean> *  * @Component * 它就相当于在配置文件中配置了一个bean标签。 * value属性用于指定bean的id * 如果没有指定value属性,bean的id就是当前类的名称,首字母改小写。 * <bean id="customerDaoImpl" class="cn.itcast.dao.impl.CustomerDaoImpl"></bean> */@Repository(value="customerDao1")public class CustomerDaoImpl implements ICustomerDao {@Overridepublic void saveCustomer() {System.out.println("保存了客户。。。。。11111111111111111111111");}}

4、在spring配置文件中开启对注解的支持

<!-- 告知spring,在创建容器时,要扫描的包 --><context:component-scan base-package="cn.itcast"></context:component-scan>

5、读取配置文件,创建对象

import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import cn.itcast.service.ICustomerService;import cn.itcast.service.impl.CustomerServiceImpl;public class Client {public static void main(String[] args) {//1.获取Spring容器ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");ICustomerDao cs1 = (ICustomerDao) ac.getBean("customerDao1");System.out.println(cs1);}}

二、常用的注解

1、用于创建对象的注解

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

@Component

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

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

@Controller  @Service  @Repository

        他们三个注解都是针对一个的衍生注解,他们的作用及属性都是一模一样的。 他们只不过是提供了更加明确的语义化。

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

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

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

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

2、用于注入数据的注解

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

@Autowired

        作用:

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

@Qualifier

        作用:

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

        属性:

                value:指定bean的id。

@Resource

        作用:

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

        属性:

                name:指定bean的id。

@Value

        作用:

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

        属性:

                value:用于指定值

public class CustomerServiceImpl implements ICustomerService {/**用于注入其他bean类型的 * @Autowired * 作用:自动按照类型注入。set方法可以不写。 *  如果没有匹配的类型,则报错。 *   如果有多个匹配的情况,它会使用变量的名称作为bean的id,如果能找到,依然可以注入成功。如果再找不到,就报错。 * @Qualifier * 作用:在自动按类型注入的基础之上,再按照bean的id注入 *  * @Resource * 作用:直接按照bean的id注入。 *  * 用于注入基本数据类型 * @Value * 作用:注入基本类型和String类型数据 *  *///@Autowired//@Qualifier(value="customerDao1")@Resource(name="customerDao2")private ICustomerDao customerDao;@Value(value="com.mysql.jdbc.Driver")private String driver;@Value(value="jdbc:mysql://localhost:3306/spring_day02")private String url;@Value(value="root")private String username;@Value(value="1234")private String password;@Overridepublic void saveCustomer() {System.out.println(driver);System.out.println(url);System.out.println(username);System.out.println(password);customerDao.saveCustomer();}/*** Autowired 注解的实现原理**/public static void main(String[] args) {Class clazz = CustomerServiceImpl.class;Field[] fs = clazz.getDeclaredFields();for(Field f : fs){boolean b = f.isAnnotationPresent(Autowired.class);if(b){Class c = f.getType();System.out.println(c);}}}}

3、用于改变作用范围的注解

@Scope
        作用:
                指定bean的作用范围。
        属性:
                value:指定范围的值。
        取值:

                singleton  

                prototype 

                request 

                session 

                globalsession

4、与生命周期相关的注解

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

@PostConstruct

        作用:

                用于指定初始化方法。

@PreDestroy

        作用:

                用于指定销毁方法。

5、代码演示

业务层代码:/** * 客户的业务层接口 * @author zhy */public interface ICustomerService {/** * 保存客户 * @param customer */void saveCustomer();}/** * 客户的业务层实现类 * @author zhy *  *///作用就相当于在xml中配置了一个bean标签,该注解有value属性,含义是bean的id。//不写的时候,默认的id是:当前类名,且首字母小写。即:customerServiceImpl@Component(value="customerService")@Scope(value="singleton")public class CustomerServiceImpl implements ICustomerService {//自动按照数据类型注入,拿着当前变量的数据类型在spring的容器中找,找到后,给变量赋值。//当有多个类型匹配时,会使用当前变量名称customerDao作为bean的id,继续在容器中找。//找到了,也能注入成功。找不到就报错。//@Autowired//@Qualifier(value="customerDao2")//在自动按照类型注入的基础之上,再按照id注入@Resource(name="customerDao2")//直接按照bean的id注入private ICustomerDao customerDao = null;@Value("com.mysql.jdbc.Driver")//注入基本类型和String类型数据private String driver;@Overridepublic void saveCustomer() {System.out.println(driver);customerDao.saveCustomer();}}持久层代码:/** * 客户的持久层接口 * @author zhy */public interface ICustomerDao {/** * 保存客户 */void saveCustomer();}/** * 客户的持久层实现类11111111111111111111 * @author zhy * */@Repository("customerDao1")public class CustomerDaoImpl implements ICustomerDao {@Overridepublic void saveCustomer() {System.out.println("保存了客户111111111111111111");}}/** * 客户的持久层实现类222222222222222222222222 * @author zhy * */@Repository("customerDao2")public class CustomerDaoImpl2 implements ICustomerDao {@Overridepublic void saveCustomer() {System.out.println("保存了客户2222222222222222222");}}测试类代码:public class Client {public static void main(String[] args) {//1.获取容器ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");//2.根据id获取对象ICustomerService cs = (ICustomerService) ac.getBean("customerService");cs.saveCustomer();}}配置文件:<?xml version="1.0" encoding="UTF-8"?><!-- 我们导入约束时,除了昨天的那部分之外,还要单独导入一个context名称空间 --><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框架在通过读取配置文件创建容器时,扫描的包,并根据包中类的注解创建对象--><context:component-scan base-package="com.itheima"></context:component-scan></beans>

6、关于xml和注解的选择的配置

注解的优势:

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

XML的优势:

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

三、spring的纯注解配置

1、配置注解类 -- 配置要扫描注解的包

package cn.itcast.config;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.Import;import org.springframework.context.annotation.PropertySource;/** * 此类就是一个配置类,用于让spring读取该类上的注解用的 *  * @Configuration * 作用:告知spring此类是一个配置类 * @ComponentScan * 作用:指定spring在创建容器时要扫描的包 * 属性: * value:指定要扫描的包名称。作用和basePackages是一模一样的。 */@Configuration@ComponentScan({"cn.itcast"})public class Configuration_A {}

2、测试类

import javax.sql.DataSource;import org.springframework.context.ApplicationContext;import org.springframework.context.annotation.AnnotationConfigApplicationContext;import cn.itcast.config.Configuration_A;public class Client {public static void main(String[] args)throws Exception {//1.获取Spring容器,参数是配置类的字节码文件ApplicationContext ac = new AnnotationConfigApplicationContext(Configuration_A.class);ICustomerService cs1 = (ICustomerService) ac.getBean("customerService");cs1.saveCustomer();}}

3、引入其他配置类的做法

@Import

(1)、被引入的配置类

package cn.itcast.config;import javax.sql.DataSource;import org.springframework.beans.factory.annotation.Value;import org.springframework.context.annotation.Bean;import com.mchange.v2.c3p0.ComboPooledDataSource;/** * @author winghze */@Component("jdbcConfig")public class JDBCConfig {@Value("com.mysql.jdbc.Driver")private String driver;@Value("jdbc:mysql://localhost:3306")private String url;@Value("root")private String username;@Value("1234")private String password;/** * 用于创建一个C3P0连接池 * @return * @throws Exception *  *   */public DataSource createDataSource() throws Exception{ComboPooledDataSource ds = new ComboPooledDataSource();ds.setDriverClass(driver);ds.setJdbcUrl(url);ds.setUser(username);ds.setPassword(password);return ds;}}

(2)、引入配置类的配置类

import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.Import;import org.springframework.context.annotation.PropertySource;/** * 此类就是一个配置类,用于让spring读取该类上的注解用的 * @author zhy *  * @Configuration * 作用:告知spring此类是一个配置类 * @ComponentScan * 作用:指定spring在创建容器时要扫描的包 * 属性: * value:指定要扫描的包名称。作用和basePackages是一模一样的。 * @Import * 作用:导入其他带有注解的类 */@Configuration@ComponentScan({"cn.itcast"})@Import({JDBCConfig.class})//@PropertySource("classpath:/cn/itcast/config/jdbc.properties")public class Configuration_A {}

(3)、测试类

import javax.sql.DataSource;import org.springframework.context.ApplicationContext;import org.springframework.context.annotation.AnnotationConfigApplicationContext;import cn.itcast.config.Configuration_A;public class Client {public static void main(String[] args)throws Exception {//1.获取Spring容器ApplicationContext ac = new AnnotationConfigApplicationContext(Configuration_A.class);JDBCConfig jc = (JDBCConfig) ac.getBean("jdbcConfig");DataSource ds = jc.createDataSource();System.out.println(dc.getConnection());}}

4、spring3以后的新注解说明

@Configuration

        作用:

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

@ComponentScan

        作用:

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

        属性:

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

@PropertySource

        作用:

                用于加载.项目下的properties文件中的配置

        属性:

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

示例代码:

(1)、配置文件类

@Configuration@ComponentScan(basePackages = "cn.itcast.spring")@PropertySource("classpath:info.properties")//加载类路径下的properties文件public class Configuration_A {}

(2)、实体类

@Component("car")public class Car {private String id ; @Value("${car.name}")//此时是读取properties文件,根据key取value了。private String name ;@Value("${car.price}")//此时是读取properties文件,根据key取value了。private Double price ;public String getId() {return id;}public void setId(String id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Double getPrice() {return price;}public void setPrice(Double price) {this.price = price;}@Overridepublic String toString() {return "Car [id=" + id + ", name=" + name + ", price=" + price + "]";} }

(3)、properties配置文件

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

@Import

        作用:

                用于导入其他配置类

        属性:

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

示例代码:

(1)、配置类

@Configuration@ComponentScan(basePackages = "cn.itcast.spring")@Import({ Configuration_B.class})public class Configuration_A {}

@Configuration@PropertySource("classpath:info.properties")public class Configuration_B {}

@Bean

        作用:

                该注解只能写在方法上,表明使用此方法创建一个对象,并且交给spring管理。简单理解为,创建对象的由自己控制,但是创建完成的对象交给spring来管理,可以使用getBean()方法获取自己创建的对象。

        属性:

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

示例代码:

@Bean(name = "datasource2")public DataSource createDS() throws Exception {ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();comboPooledDataSource.setUser("root");comboPooledDataSource.setPassword("1234");comboPooledDataSource.setDriverClass("com.mysql.jdbc.Driver");comboPooledDataSource.setJdbcUrl("jdbc:mysql:///spring_ioc");return comboPooledDataSource;}