九点钟☆方向

记录成长点滴

欢迎来到我的个人博客~


Spring笔记(五) Spring注解补充

目录

经过前一篇的案例,我们发现不管是xml还是注解方式,都还会有Spring的配置文件bean.xml,该文件可以通过本节讲解的注解进行去除。

现在bean.xml中还有两部分内容,一是要告知Spring要扫描的包,二是要配置runner和DataSource

注解

@Configuration

作用:用于指定当前类是一个 spring 配置类(相当于Spring配置文件bean.xml), 当创建容器时会从该类上加 载注解。 获取容器时需要使用AnnotationApplicationContext(有@Configuration 注解的类.class) 属性: value:用于指定配置类的字节码

@Configuration
public class SpringConfiguration {    }

注意当配置类作为AnnotationConfigApplicationContext对象创建的参数时该注解可以不写
new AnnotationConfigApplicationContext(SpringConfig.class);
此时SpringConfig.class作为参数,那么SpringConfig类上的@Configuration注解可以不写

@ComponentScan

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

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

value:和basePackages作用一样。

两个属性写哪个都可以,作用一致

//这两个注解就可以将bean.xml中的扫描包配置去掉
@Configuration //代表spring 的配置类,相当于 bean.xml 文件
@ComponentScan("com.mg") //指定扫描的包
public class SpringConfiguration {    }

@Bean

作用:该注解只能写在方法上,把当前方法的返回值作为bean对象存入Spring的IOC容器 属性: name:用于指定 bean 的 id,不写时默认是当前方法名称

@Configuration
@ComponentScan(basePackages = "com.mg")
public class SpringConfig {

    //配置DataSource
    @Bean(name="dataSource")
    public DataSource createDataSource() {
        try {
            ComboPooledDataSource ds = new ComboPooledDataSource();
            ds.setUser("root");
            ds.setPassword("root");
            ds.setDriverClass("com.mysql.jdbc.Driver");
            ds.setJdbcUrl("jdbc:mysql://localhost:3306/spring");
            return ds;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    //配置queryRunner
    @Bean(name = "queryRunner")
    @Scope("prototype")
    public QueryRunner createQueryRunner(DataSource dataSource) {
        return new QueryRunner(dataSource);
    }
}

 细节当使用注解配置方法时如果方法有参数spring回去容器中查找有无可用的bean对象查找方式和
 Autowired注解一致所以写createQueryRunner方法时如果没有先定义DataSource则此处会报红
 如果存在多个对象可以使用@Qualifier指定使用哪一个

此时用以上几个注解就可以将Spring的配置文件移除了。

测试使用:要注意使用AnnotationConfigApplicationContext这个类

@Test
public void test2() {
    ApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfig.class);
    IAccountService accountService = ac.getBean("accountService", IAccountService.class);
    List<Account> accounts = accountService.findAllAccount();
    for(Account account:accounts) {
        System.out.println(account);
    }
}

注意
new AnnotationConfigApplicationContext(SpringConfig.class);此处的参数要写配置类可以写多个
此时SpringConfig.class作为参数,那么SpringConfig类上的@Configuration注解可以不写

@Import

作用:用于导入其他配置类。引入的其他配置类可以不用再写@Configuration 注解。 当然写上也没问题。 属性: value[]:用于指定其他配置类的字节码。

//主配置类
@Configuration
@ComponentScan(basePackages = "com.mg")
@Import(JdbcConfig.class)//参数可以写多个
public class SpringConfig {    }


//JDBC配置类
//@Configuration   可以写也可以不写
public class JdbcConfig {

    @Bean(name="dataSource")
    public DataSource createDataSource() {
        try {
            ComboPooledDataSource ds = new ComboPooledDataSource();
            ds.setUser("root");
            ds.setPassword("root");
            ds.setDriverClass("com.mysql.jdbc.Driver");
            ds.setJdbcUrl("jdbc:mysql://localhost:3306/spring");
            return ds;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Bean(name = "queryRunner")
    @Scope("prototype")
    public QueryRunner createQueryRunner(DataSource dataSource) {
        return new QueryRunner(dataSource);
    }
}
当我们使用了@Import注解后@Import注解的类就是主配置类导入的都是子配置类
如有几个配置类关于JDBC的关于事务的都可以使用@Import导入


//使用时,只需要传入主配置类就可以了
ApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfig.class);

如果不使用@Import注解,使用其他方式也可以达到同样的效果,比如:

第一种:可以将子配置类作为参数传递过去

ApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfig.class,
                                                               JdbcConfig.class);

第二种:子配置类中加入Configuration注解,并在主配置类的扫描包里面加入子配置类所在的包

@Configuration
//所在包为  com.config
public class JdbcConfig {    }

@Configuration
@ComponentScan(basePackages = "com.mg","com.config")
public class SpringConfig {    }

使用时
ApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfig.class)

@PropertySource

作用:用于加载.properties 文件中的配置。例如我们配置数据源时,可以把连接数据库的信息写到properties 配置文件中,就可以使用此注解指定 properties 配置文件的位置。 属性: value[]:用于指定 properties 文件位置。如果是在类路径下,需要写上 classpath:

//如之前用@Bean创建DataSource时,数据库信息写死,则可以修改为:
1. 创建jdbcConfig.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/spring
jdbc.username=root
jdbc.password=root


2.类中修改
//引入properties文件,写配置文件的具体位置,如果是在类路径下,需要写上 classpath: 
@PropertySource("classpath:jdbcConfig.properties")
public class JdbcConfig {
	//获取properties文件的值
    @Value("${jdbc.driver}")
    private String driver;
    @Value("${jdbc.url}")
    private String url;
    @Value("${jdbc.username}")
    private String username;
    @Value("${jdbc.password}")
    private String password;

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

    @Bean(name = "queryRunner")
    @Scope("prototype")
    public QueryRunner createQueryRunner(DataSource dataSource) {
        return new QueryRunner(dataSource);
    }
}


//注意:@PropertySource("classpath:jdbcConfig.properties")这个注解也可以加到主配置类上
//主配置类
@Configuration
@ComponentScan(basePackages = "com.mg")
@Import(JdbcConfig.class)
@PropertySource("classpath:jdbcConfig.properties")
public class SpringConfig {   }


//子配置类
public class JdbcConfig {
	//获取properties文件的值
    @Value("${jdbc.driver}")
    ………………………………………………………………
}

@Qualifier

另一种用法,使用在参数上,可单独使用。如有多个对象时,需要使用该注解指定用哪个,使用注解时如果方法有参数,Spring回去容器中查找是否有可用对象,查找方式和AutoWired一致,即:按照类型找到唯一一个则注入成功,找到多个则把参数名作为bean的id去找,找到也可以注入成功,如果还不能唯一确定则报错

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

@Bean(name="ds1")
public DataSource ds1() {    }

@Bean(name="ds2")
public DataSource ds2() {    }

spring的IOC实现账户的CRUD(纯注解实现)

引入依赖

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.2.8.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>commons-dbutils</groupId>
        <artifactId>commons-dbutils</artifactId>
        <version>1.7</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.6</version>
    </dependency>
    <dependency>
        <groupId>c3p0</groupId>
        <artifactId>c3p0</artifactId>
        <version>0.9.1.2</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.13</version>
    </dependency>
</dependencies>

建表

create table account (
	id int primary key auto_increment,
	name varchar (40),
	money float
	)character set utf8 collate utf8_general_ci;


	insert into account(name, money) values('aaa', 1000);
	insert into account (name,money) values ('bbb',1000);
	insert into account (name, money) values('ccc', 1000) ;

实体类

public class Account implements Serializable {
    private Integer id;
    private String name;
    private Float money;
    //生成set/get
}

Service接口及实现类

public interface IAccountService {
    List<Account> findAllAccount();
}


@Service("accountService")
public class AccountServiceImpl implements IAccountService {
    @Autowired
    private IAccountDao accountDao;

    public List<Account> findAllAccount() {
        return accountDao.findAllAccount();
    }
}

Dao接口及实现类

public interface IAccountDao {
    List<Account> findAllAccount();
}

@Repository("accountDao")
public class AccountDaoImpl implements IAccountDao {
    @Autowired
    private QueryRunner queryRunner;

    public List<Account> findAllAccount() {
        try {
            return queryRunner.query("select * from account",
                                     new BeanListHandler<Account>(Account.class)
                                    );
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
}

数据库相关配置文件 jdbcConfig.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/spring
jdbc.username=root
jdbc.password=root

Spring配置类

JDBC相关配置类,子配置类
//@Configuration   可以写也可以不写
@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;

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

    @Bean(name = "queryRunner")
    @Scope("prototype")
    public QueryRunner createQueryRunner(DataSource dataSource) {
        return new QueryRunner(dataSource);
    }
}
Spring主配置类
@Configuration
@ComponentScan(basePackages = "com.mg")
@Import(JdbcConfig.class)
public class SpringConfig {   }

测试使用

@Test
public void test2() {
    ApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfig.class);
    IAccountService accountService = ac.getBean("accountService", IAccountService.class);
    List<Account> accounts = accountService.findAllAccount();
    for(Account account:accounts) {
        System.out.println(account);
    }
}

打赏一个呗

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦