SSM2==springframework。纯注解配置spring实现IOC的5种方法和实现DI注入简单数据类型、引用数据类型和第三方依赖。spring纯注解配置Druid和Mybatis和Junit

一:注解实现IOC,5种注解 将一个类/接口的创建销毁交给spring IOC容器管理。
        
        <bean id = "bookDao" class = "com.itheima.dao.impl.BookDaoImpl" />

        在使用XML声明一个类为bean我们使用的语法如上,通过这样的语言我们将BookDao交给了spring IOC容器管理,IOC容器通过默认的无参构造实例化bean。

       使用注解开发时,上述语句用这种方式代替:直接在类上使用@Component("bookDao")注解,并且在配置文件中书写

        <context:component-scan base-package="com.ldj"></context:component-scan>

         @Component的衍生注解有三个,基本功能是和@Component一模一样,唯一的用处就是便于我们识别类的具体信息,方便阅读,如下:

                1、@controller: controller控制器层(注入服务)
                2、@service : service服务层(注入dao)
                3、@repository : dao持久层(实现dao访问)
                4、@component: 标注一个类为Spring容器的Bean,(把普通pojo实例化到spring容器中,相当于配置文件中的,比如工具类)

                1、@Service用于标注业务层组件
                2、@Controller用于标注控制层组件(如struts中的action)
                3、@Repository用于标注数据访问组件,即DAO组件.
                4、@Component泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注,标识为一个Bean,比如工具类。

       还有种声明bean的方式是在方法上使用@Bean注解,获取方法的返回值作为bean交给IOC容器管理,主要用于引入第三方依赖包。

=============================================================

        怎样使用注解控制bean的作用范围(控制是否单例)?在声明为bean的同时使用注解来控制,@Scope("prototype) @Scope("singleton”)

        怎样使用注解控制bean的生命周期?在bean类的成员方法上使用注解来控制,极少使用,且JDK 11下使用会失效,:(init-method,destory-method):@PostConstruct  @PreDestory

============================================================= 

        上述我们已经将类声明为IOC容器管理的bean,那么如何从IOC容器中取出bean并且使用?有两种方式。

获取IOC容器和bean的方式,当bean用注解声明,将spring配置文件依然通过XML来书写如下:

        ApplicationContext ctx = new
ClassPathXmlApplicationContext ( "applicationContext.xml" );
获取IOC容器和bean的方式,bean用注解声明,将spring配置文件也通过配置类来书写,如下:

        配置类上使用注解@Configuration @ComponentScan表示这是一个替换XML的配置类。

         获取IOC容器和bean通过AnnotationConfigApplicationContext或者使用

                AnnotationConfigWebApplicationContext

        ApplicationContext ctx = new AnnotationConfigApplicationContext ( SpringConfig . class );

===============================================================

2、注解实现DI依赖注入

        前提,是在一个已经被声明为bean的类或者方法中才能使用

       (1) 注入简单数据类型@PropertySource("路径")搭配@Value("${name}")

        注入.properties文件中的数据:配置类上使用@Configuration @ComponentScan("包路径")@PropertySource("路径"),路径不支持通配符*,源码中有对应说明。bean中获取值使用是通过@Value("${name}")

       (2) 注入简单的引用数据类型@Component4种 搭配 @Autowired或@Autowired+@Qualifier("首字母小写名字")

        前提:这个引用数据类型对应的类已经是一个通过之前的5种方式交给IOC容器管理的bean!spring注解开发是为了让我们加速开发,所以不是所有的DI方式spring都提供了对应的注解。目前普遍使用的是通过自动装配实现DI:@Autowired,本质是自动装配的byType,本来应该还要写setter,但是这个注解直接把这一步也简化了不需要写,原理是暴力反射直接访问private修饰对象。

        具体使用时候,只有一个实现类的话,直接写@Autowired。有多个实现类,按传统是要byname,注解开发是使用@Autowired+@Qualifier("首字母小写的名字")

        (3)注入复杂的引用数据类型注解开发第三方bean管理)@Value @Bean @Import({JdbcConfig.class})

        通过上一篇文章我们实现了纯XML配置第三方的bean,那使用纯注解怎么实现第三方bean的IOC和DI,比如DRUID和mybatis?因为他们的源码我们是无法进去打注解的,所以只能使用编程的方式,挨个写。 

        比如将DRUID的DruidDataSource的实例化交给IOC容器管理,我们需要写一个方法,方法内部new一个DruidDataSource对象,给对象的各种成员变量赋值(赋的值可以通过@Value获得),然后将对象作为返回值,在方法上标注@Bean,spring会自动将该方法的返回值作为bean来管理,我们可以通过IOC容器getBean获取它,也可以通过DI将它注入到其他地方。详见后面的“注解开发spring配置DRUID连接池

        比如将mybatis的SqlSessionFactoryBean的实例化交给IOC容器管理。详见后边的“注解开发spring配置Mybatis

        (4)重点:参考上述三种方法一个bean A还需要注入其他bean B呢?

        简单数据类型如上所述,写成成员变量打上注解即可:

注入简单数据类型:@Value("值")

注入.properties文件中的数据:@Configuration @ComponentScan("包路径")@PropertySource("路径"),路径不支持通配符*,源码中有对应说明。获取值@Value(${"key"})

        引用数据类型:直接在 @Bean   所在的方法中写需要注入的依赖B,将它作为参数即可,因为A被 @Bean  注解,spring会自动装配A需要的参数。但前提是B已经是一个交给IOC容器管理的BEAN,即带了@Component等四个注解或者带了@Bean注解。

====================================================

XML和注解开发的对比

=======================================================================

3、注解开发spring配置DRUID连接池

         首先我们来看XML配置连接池,步骤为:           

        1、新建一个maven基础项目,导入springframework基础依赖包spring-context

         2、导入DRUID、jdbc、junit依赖包

         3、编辑spring配置文件,读取存账号密码等的properties文件。需要用到context命名空间,所以先改xmlns和xsi

         4、将DruidDataSource 配置成一个由IOC容器管理的bean,并指定实例化方法为默认的空参构造方法实例化bean。见“SSM1==springframework。XML实现IOC的4种方式,实现DI的8种方式。”

         5、根据DruidDataSource 的源码选择DI依赖注入的实现方式为setter注入。根据源码可以得知,DruidDataSource类只有两个构造器,而且他能用的参数比较多,使用者是根据自己的需求配置参数,阿里也没法挨个提供相应的构造器。所以只能用setter注入方式。“SSM1==springframework。XML实现IOC的4种方式,实现DI的8种方式。”

        6、获取bean得到一个DruidDataSource对象,getConnection获取Connection对象,进行CRUD操作。

        同理,通过注解来配置DRUID连接池也大概遵循上述几个步骤:

         1、新建一个maven基础项目,导入springframework基础依赖包spring-context

         2、导入DRUID、jdbc、junit依赖包

         3、通过@Configuration编写spring配置类替代配置文件,通过配置类上使用  

@PropertySource("路径")指定数据库连接信息存放的properties文件的地址,在需要使用数据库信息的bean中通过@Value(${"key"})读取properties文件中存放的账号密码等。

         4、通过@Bean将DruidDataSource 配置成一个由IOC容器管理的bean

         5、可以看到在XML配置中,我们是将连接池配置写在spring配置文件中的,实际上也有更好的方式,将连接池配置单独写一个XML,然后导入spring的配置文件中。

        所以本次使用注解开发时,我们将连接池配置单独写一个配置类,然后import进spring的配置类中,通过在spring配置类上写@Import({连接池配置类名字.class})将连接池的配置类导入到spring的配置类。这样的好处是我们编写的时候是分开写的,有利于解耦。

        当然也可以不写@Import({JdbcConfig.class}),直接将连接池配置直接写在spring的配置类里。

        6、获取bean得到一个DruidDataSource对象,getConnection获取Connection对象,进行CRUD操作。

=========================================================================

4、注解开发spring配置Mybatis

首先,我们来看XML配置mybatis,步骤为:  

        1、新建一个MAVEN项目,导入依赖

        2、编写entity、mapper、mapper.xml、service

        3、编写数据库properties配置文件

        4、编写spring配置文件:将DataSource作为bean并通过setter注入必要的参数,将SqlSessionFactory通过SqlSessionFactoryBean作为bean并通过setter DI注入DataSource和必要的参数,将mapper作为bean并通过setter注入SqlSessionFactory,将service作为bean并通过自动装配DI注入mapper。

        FactoryBean接口第三方框架中与spring结合时会大量使用。工厂模式在实际开发中,是大量使用的,针对这种工厂创建bean的开发,基本上就是使用FactoryBean,并且结合动态代理的模式可以帮助我们更好的去完善拓展我们的业务逻辑。但是一般不用我们自己去拓展,比如mybatis官方提供的mybatis-spring已经帮我实现了FactoryBean接口,实现类就叫SqlSessionFactoryBean。

         XML配置mybatis的配置文件如下,方便对比

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="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-4.0.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-4.0.xsd">
 
    <!--导入属性文件 这样其中的数据就可以用占位符访问-->
    <context:property-placeholder location="classpath:db/db.properties"></context:property-placeholder>
 
    <!--将连接池交给spring IOC容器管理:配置数据源-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${db.driveClass}"></property>
        <property name="url" value="${db.url}"></property>
        <property name="username" value="${db.username}"></property>
        <property name="password" value="${db.password}"></property>
    </bean>
 
    <!--将mybatis工厂交给spring IOC容器管理:sqlsessionfactory的配置,获取到的是DefaultSqlSessionFactory对象-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"></property>
        <property name="mapperLocations" value="classpath:mapper/BookMapper.xml"></property>
    </bean>
 
    <!--将mapper交给spring IOC容器管理:mapper扫描,不用配置ID,使用时候直接首字母小写即可调用,方便多个mapper管理-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
        <!--dao 接口所对应的包-->
        <property name="basePackage" value="com.ldj.mapper"></property>
    </bean>
 
    <!--将service交给spring IOC容器管理:autowire属性:开启自动装配,因为只使用了一个Mapper,所以使用按类型自动装配
    。一定要在service中写对应的setter,因为实际上默认也是使用setter注入,只是减少了spring配置的书写,不用再写property配置属性了,
    但没简化类的书写。
    而且我们上面的mapper是用的免写ID的方式,所以这里最好也用自动装配。
    当然也可以采用实例化方式中的构造器注入,因为没有ID,可以通过index和type来指定注入的东西-->
    <bean id="bookService" class="com.ldj.service.BookService" autowire="byType"/>
 
</beans>

        5、测试

        通过分析XML配置,关键是确认哪些是核心对象,注解配置mybatis重点就是把那几个核心对象通过@Bean交给IOC管理就行了,步骤如下:

        1、新建一个MAVEN项目,导入依赖

        2、编写entity、mapper、mapper.xml、service

        3、编写数据库properties配置文件

        4、编写spring配置文件:

                        (1)编写主配置文件SpringConifg替换原本的XML配置文件,并在主配置类上使用@Configuration声明它是主配置类,使用@ComponentScan指定从哪些包下扫描获取到需要IOC容器管理的bean,使用@PropertySource("classpath:db/db.properties")指定数据库信息存放的地址方便JdbcConfig使用,使用@Import导入分配置类JdbcConfig和MybatisConfig

                        (2)编写分配置类JdbcConfig替换原本XML配置文件中的DataSource获取部分。使用@Value获取主配置类@PropertySource指向的properties文件中的值,使用@Bean注解一个方法,将方法的返回值DataSource声明为一个bean。

                         (3)编写分配置类MybatisConfig替换原本XML配置文件中的SqlSessionFactory和MapperScannerConfigurer部分。使用@bean注解一个方法,将方法的返回值SqlSessionFactoryBean和MapperScannerConfigurer声明为bean。注意方法的参数是spring自动装配中的byType,对应接口的实现类只能有一个!

                          (4)原配置文件中将service也声明为了一个bean,并将mapper注入到了service。采用注解的话在service上写上@Component或者它衍生出的@Service,再用@Autowired注解引入引用数据类型mapper即可。

           5、使用

        项目结构:

 XML配置与注解配置比对:

========================================================================= 

spring通过纯注解整合Druid、mybatis完整代码:

测试数据

/*

Source Database       : spring_db

*/

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for tb_account
-- ----------------------------
DROP TABLE IF EXISTS `tb_account`;
CREATE TABLE `tb_account` (
  `id` int(255) NOT NULL AUTO_INCREMENT,
  `name` varchar(35) DEFAULT NULL,
  `money` double DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of tb_account
-- ----------------------------
INSERT INTO `tb_account` VALUES ('1', '22', '33');
SpringConfig
package com.ldj.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;

@Configuration
@ComponentScan("com.ldj")
//@PropertySource:加载类路径jdbc.properties文件
@PropertySource("classpath:db/db.properties")
@Import({JdbcConfig.class,MybatisConfig.class})
public class SpringConfig {
}
db.properties

db.driveClass=com.mysql.cj.jdbc.Driver
db.username=root
db.password=1234
db.url=jdbc:mysql:///spring_db?useSSL=false&amp&useServerPrepStmts=true
JdbcConfig
package com.ldj.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;

import javax.sql.DataSource;


public class JdbcConfig {
    @Value("${db.driveClass}")
    private String driver;
    @Value("${db.url}")
    private String url;
    @Value("${db.username}")
    private String userName;
    @Value("${db.password}")
    private String password;

    @Bean
    public DataSource dataSource(){
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName(driver);
        ds.setUrl(url);
        ds.setUsername(userName);
        ds.setPassword(password);
        return ds;
    }
}
MybatisConfig
package com.ldj.config;

import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.context.annotation.Bean;

import javax.sql.DataSource;

public class MybatisConfig {
    //定义bean,SqlSessionFactoryBean,用于产生SqlSessionFactory对象
    @Bean
    public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource){
        //DataSource此处的实现类只有一个即DruidDataSource,所以mybatis自动装配时自动找到实现类
        SqlSessionFactoryBean ssfb = new SqlSessionFactoryBean();
        ssfb.setTypeAliasesPackage("com.ldj.domain");
        ssfb.setDataSource(dataSource);
        return ssfb;
    }
    //定义bean,返回MapperScannerConfigurer对象
    @Bean
    public MapperScannerConfigurer mapperScannerConfigurer(){
        MapperScannerConfigurer msc = new MapperScannerConfigurer();
        msc.setBasePackage("com.ldj.mapper");
        return msc;
    }
}



AccountDao.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ldj.mapper.AccountDao">
    <select id="selectAll" resultType="com.ldj.domain.Account">
        select * from tb_account;
    </select>
</mapper>

实体类Account,没写setter getter需要加上

package com.ldj.domain;

import java.io.Serializable;

public class Account implements Serializable {

    private Integer id;
    private String name;
    private Double money;
AccountDao
package com.ldj.mapper;

import com.ldj.domain.Account;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

import java.util.List;

public interface AccountDao {

//    @Insert("insert into tbl_account(name,money)values(#{name},#{money})")
//    void save(Account account);
//
//    @Delete("delete from tbl_account where id = #{id} ")
//    void delete(Integer id);
//
//    @Update("update tbl_account set name = #{name} , money = #{money} where id = #{id} ")
//    void update(Account account);


    List<Account> selectAll();

//    @Select("select * from tbl_account where id = #{id} ")
//    Account findById(Integer id);
}
AccountService
package com.ldj.service;

import com.ldj.domain.Account;

import java.util.List;

public interface AccountService {
//
//    void save(Account account);
//
//    void delete(Integer id);
//
//    void update(Account account);
//
    List<Account> selectAll();

//    Account findById(Integer id);

}
AccountServiceImpl
package com.ldj.service.impl;

import com.ldj.mapper.AccountDao;
import com.ldj.domain.Account;
import com.ldj.service.AccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class AccountServiceImpl implements AccountService {

    @Autowired
    private AccountDao accountDao;

//    public void save(Account account) {
//        accountDao.save(account);
//    }
//
//    public void update(Account account){
//        accountDao.update(account);
//    }
//
//    public void delete(Integer id) {
//        accountDao.delete(id);
//    }
//
//    public Account findById(Integer id) {
//        return accountDao.findById(id);
//    }

    public List<Account> selectAll() {
        return accountDao.selectAll();
    }
}
SpringTest
import com.ldj.config.SpringConfig;
import com.ldj.service.AccountService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

//设置类运行器
@RunWith(SpringJUnit4ClassRunner.class)
// 设置Spring环境对应的配置类
@ContextConfiguration(classes = {SpringConfig.class}) //加载配置类
public class SpringTest {
    //下面就能直接测试IOC容器持有的bean了,不需要我们自己先获取IOC容器,然后调用方法取出bean
    @Autowired
    private AccountService accountService;

    @Test
    public void testSelectAll() {
        System.out.println(accountService.selectAll());
    }
}

spring整合Junit测试结果:简化了啥?我们不用在写获取容器再从容器中取得bean那段代码了,我们可以直接注解获取bean,然后调用方法。

步骤:

        新建一个测试类,在测试类上注解@RunWith指定用哪家的测试工具,除了Junit还有其他家也能测试,同时注解@ContextConfiguration指定需要测试的spring项目的主配置类。

        @Autowied等获取bean,@Test测试方法

        至此,我们完成了 注解配置spring实现IOC和DI,spring纯注解配置DRUID和Mybatis。mybatis的mapper映射文件也可以直接使用mybatis依赖包提供的注解。

        使用spring注解配置不只有文中所写的方式,还有其他的方式,根据IOC和DI实现就行。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值