[笔记]Spring-Day2 — 注解开发

IOC/DI配置管理第三方bean

案例:配置Druid

环境准备

  1. 创建maven项目

  2. pom.xml添加依赖 spring-context

  3. resources下添加 applicationContext.xml

  4. 编写运行类 ApplicationContext ctx

pom.xml导入 druid 依赖

配置类配置第三方bean

    <!--管理DruidDataSource对象-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/spring_db"/>
        <property name="username" value="root"/>
        <property name="password" value="950827"/>
    </bean>
    </beans>

从IOC容器中获取对应的bean对象

    public class App {
        public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        DataSource dataSource = (DataSource) ctx.getBean("dataSource");
        System.out.println(dataSource);
        }
    }

注意事项

  1. 对于新的技术,不知道具体的坐标该如何查找?

    1. 百度

    2. 从mvn的仓库https://mvnrepository.com/中进行搜索

  2. 报的错为ClassNotFoundException,具体的类为com.mysql.jdbc.Driver错误的原因是缺少mysql的驱动包

    1. 在pom.xml把驱动包引入即可

加载properties文件

原因: 属性写在Spring的配置文件中不利于后期维护 ​ —> 将这些值提取到一个外部的properties配置文件中

具体步骤:

resources下创建一个jdbc.properties文件

    jdbc.driver=com.mysql.jdbc.Driver
    jdbc.url=jdbc:mysql://127.0.0.1:3306/spring_db
    jdbc.username=root
    jdbc.password=root

开启context命名空间、加载properties配置文件、完成属性注入

    <?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">
        <!--加载properties配置-->
        <context:property-placeholder location="jdbc.properties"/>
        <!--**完成属性注入**-->
        <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${jdbc.driver}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
        </bean>
    </beans>

多个property文件需要加载时

 <!--方式一 -->
 <context:property-placeholder location="jdbc.properties,jdbc2.properties" system-properties-mode="NEVER"/>
 <!--方式二-->
 <context:property-placeholder location="*.properties" system-properties-mode="NEVER"/>
 <!--方式三 -->
 <context:property-placeholder location="classpath:*.properties" system-properties-mode="NEVER"/>
 <!--方式四-->
 <context:property-placeholder location="classpath*:*.properties" system-properties-mode="NEVER"/>
 </beans>

核心容器

简单的理解为ApplicationContext

容器的创建方式

 //类路径下的XML配置文件    掌握
 ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
 //文件系统下的XML配置文件  了解
 ApplicationContext ctx = new FileSystemXmlApplicationContext("D:\\workspace\\spring\\spring_10_container\\src\\main\\resources\\applicationContext.xml");

bean的三种获取方式

    //方式一   getBean("名称"):需要类型转换
    BookDao bookDao = (BookDao) ctx.getBean("bookDao");
    //方式二    getBean("名称",类型.class):多了一个参数
    BookDao bookDao = ctx.getBean("bookDao",BookDao.class);
    //方式三    容器中不能有多个该类的bean对象
    BookDao bookDao = ctx.getBean(BookDao.class);

容器类层次结构

  • 容器的最上级的父接口为 BeanFactory

BeanFactory —额额不太懂

使用BeanFactory来创建IOC容器

    public class AppForBeanFactory {
        public static void main(String[] args) {
            Resource resources = new ClassPathResource("applicationContext.xml");
            //创建了一个bf的IOC容器
            BeanFactory bf = new XmlBeanFactory(resources);
            BookDao bookDao = bf.getBean(BookDao.class);
            bookDao.save();
        }
    }

总结

  • 使用BeanFactory创建的容器是延迟加载

  • 使用ApplicationContext创建的容器是立即加载

  • 具体BeanFactory如何创建只需要了解即可

IOC/DI注解开发

注解开发定义bean

  1. 环境准备

  2. 删除原XML配置的<bean>标签

  3. Dao上添加@Component注解

  4. 配置Spring的注解包扫描 @ComponentScan

  5. ServiceImpl类上也添加@Component

  6. 运行行为类测试

XML与注解配置的对应关系

@Controller@Service@Repository

纯注解开发模式

  • 将配置文件applicationContext.xml删除掉,使用类来替换

【❗更新】环境准备

  1. 创建maven

  2. pom.xml

  3. springconfig【刚学的注解开发定义bean】

  4. 添加类

创建一个配置类SpringConfig 、标识该类为配置类、用注解替换包扫描配置

    //将其标识为一个配置类,替换`applicationContext.xml`
    @Configuration  
    //替换`<context:component-scan base-package=""/>`
    @ComponentScan("com.itheima")
    public class SpringConfig {
    }

创建运行类并执行

    public class AppForAnnotation {
        public static void main(String[] args) {
            ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
            BookDao bookDao = (BookDao) ctx.getBean("bookDao");
            System.out.println(bookDao);
            BookService bookService = ctx.getBean(BookService.class);
            System.out.println(bookService);
        }
    }

注解开发bean的作用范围和生命周期管理

    @Scope("prototype")   //@Scope设置bean的作用范围
    @Repository
    public class BookDaoImpl implements BookDao {
        public void save() {
                System.out.println("book dao save ...");
        }
        @PostConstruct //在构造方法之后执行,替换 init-method
        public void init() {
            System.out.println("init ...");
        }
        @PreDestroy //在销毁方法之前执行,替换 destroy-method
        public void destroy() {
            System.out.println("destroy ...");
        }
    }

注解对应关系图

注解开发依赖注入

bean和service的关系

  • 之前的配置文件application配置好的bean和service的关系还没用注解开发,所以bookDao对象为Null,调用其save方法就会报空指针异常

  • 解决办法:在BookServiceImpl类的bookDao属性上添加@Autowired注解

    @Service
    public class BookServiceImpl implements BookService {
        @Autowired
        private BookDao bookDao;
            //	  public void setBookDao(BookDao bookDao) {
            //        this.bookDao = bookDao;
            //    }
        public void save() {
            System.out.println("book service save ...");
            bookDao.save();
        }
    }

按照名称注入

  • 如果Dao接口类有多个实现类,解决方案:按照名称注入

DaoImpl文件

    //起别名
    @Repository("bookDao")
    public class BookDaoImpl implements BookDao {
        public void save() {
        	System.out.println("book dao save ..." );
        }
    }
        @Repository("bookDao2")
        public class BookDaoImpl2 implements BookDao {
            public void save() {
                System.out.println("book dao save ...2" );
            }
    }

ServiceImpl文件

    @Service
    public class BookServiceImpl implements BookService {
        @Autowired
        @Qualifier("bookDao1")
        private BookDao bookDao;

        public void save() {
            System.out.println("book service save ...");
            bookDao.save();
        }
    }

简单数据类型注入

DaoImpl文件

    @Repository("bookDao")
    public class BookDaoImpl implements BookDao {
        **private String name;**
        public void save() {
        	System.out.println("book dao save ..." + name);
        }
    }

ServiceImpl文件

    @Repository("bookDao")
    public class BookDaoImpl implements BookDao {
        **@Value("itheima")**
        private String name;
        public void save() {
        	System.out.println("book dao save ..." + name);
        }
    }

注解读取properties配置文件

resource下准备properties文件

springconfig加载properties配置文件

    @Configuration
    @ComponentScan("com.itheima")
    //如果要指定多个配置文件,不支持使用通配符*
    //1.@PropertySource({"jdbc.properties","xxx.properties"})
    //2.@PropertySource({"classpath:jdbc.properties"})
    @PropertySource("jdbc.properties")
    public class SpringConfig {
    }

DaoImpl读取配置文件中的内容

    @Repository("bookDao")
    public class BookDaoImpl implements BookDao {
        **@Value("${name}")**
        private String name;
        public void save() {
        	System.out.println("book dao save ..." + name);
        }
    }

IOC/DI注解开发管理第三方bean

- 第三方的类都是在jar包中,我们没有办法在类上面添加注解?

案例:注解开发管理第三方bean

导入对应的jar包

在配置类中添加一个方法、添加@Bean注解

    @Configuration
    public class SpringConfig {
        **@Bean**
        public DataSource dataSource(){
            DruidDataSource ds = new DruidDataSource();
            ds.setDriverClassName("com.mysql.jdbc.Driver");
            ds.setUrl("jdbc:mysql://localhost:3306/spring_db");
            ds.setUsername("root");
            ds.setPassword("950827");
            return ds;
        }
    }

从IOC容器中获取对象并打印

    public class App {
        public static void main(String[] args) {
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
        DataSource dataSource = ctx.getBean(DataSource.class);
        System.out.println(dataSource);
    }
}

引入外部配置类

新建一个JdbcConfig配置类

    public class JdbcConfig {
        @Bean
        public DataSource dataSource(){
            DruidDataSource ds = new DruidDataSource();
            ds.setDriverClassName("com.mysql.jdbc.Driver");
            ds.setUrl("jdbc:mysql://localhost:3306/spring_db");
            ds.setUsername("root");
            ds.setPassword("root");
            return ds;
        }
    }

在Spring配置类中引入 @import

    @Configuration
    //@ComponentScan("com.itheima.config")
    //@Import参数需要的是一个数组,可以引入多个配置类
    @Import({JdbcConfig.class})
    public class SpringConfig {

    }

注解开发实现为第三方bean注入资源

简单数据类型

—— 使用@Value注解引入值

    public class JdbcConfig {
        @Value("com.mysql.jdbc.Driver")
        private String driver;
        @Value("jdbc:mysql://localhost:3306/spring_db")
        private String url;
        @Value("root")
        private String userName;
        @Value("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;
        }
    }

引用数据类型

在SpringConfig中扫描BookDao

—— @ComponentScan("com.itheima.dao")

在JdbcConfig类的方法上添加参数

    @Bean
    public DataSource dataSource(BookDao bookDao){
        //在这里!
        **System.out.println(bookDao);**
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName(driver);
        ds.setUrl(url);
        ds.setUsername(userName);
        ds.setPassword(password);
        return ds;
    }

注解开发总结

Untitled

spring整合! --整合Mybatis

环境准备

数据库表

    create database spring_db character set utf8;
    use spring_db;
    create table tbl_account(
        id int primary key auto_increment,
        name varchar(35),
        money double
    );

创建项目导入jar包**

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.2.10.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.1.16</version>
    </dependency>
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.6</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.47</version>
     </dependency>
</dependencies>

根据表创建模型类

public class Account implements Serializable {
        private Integer id;
        private String name;
        private Double money;
        //setter...getter...toString...方法略    
    }

创建Dao接口

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);

    @Select("select * from tbl_account")
    List<Account> findAll();

    @Select("select * from tbl_account where id = #{id} ")
    Account findById(Integer id);
}

创建Service接口和实现类

    public interface AccountService {
        void save(Account account);
        void delete(Integer id);
        void update(Account account);
        List<Account> findAll();
        Account findById(Integer id);
    }

    @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> findAll() {
        	return accountDao.findAll();
        }
    }

添加jdbc.properties文件

    jdbc.driver=com.mysql.jdbc.Driver
    jdbc.url=jdbc:mysql://localhost:3306/spring_db?useSSL=false
    jdbc.username=root
    jdbc.password=root

添加Mybatis核心配置文件

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE configuration
    PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-config.dtd">
    <configuration>
    <!--读取外部properties配置文件-->
    <properties resource="jdbc.properties"></properties>
    <!--别名扫描的包路径-->
    <typeAliases>
    <package name="com.itheima.domain"/>
    </typeAliases>
    <!--数据源-->
    <environments default="mysql">
    <environment id="mysql">
    <transactionManager type="JDBC"></transactionManager>
    <dataSource type="POOLED">
    <property name="driver" value="${jdbc.driver}"></property>
    <property name="url" value="${jdbc.url}"></property>
    <property name="username" value="${jdbc.username}"></property>
    <property name="password" value="${jdbc.password}"></property>
    </dataSource>
    </environment>
    </environments>
    <!--映射文件扫描包路径-->
    <mappers>
    <package name="com.itheima.dao"></package>
    </mappers>
    </configuration>

编写应用程序

public class App {
    public static void main(String[] args) throws IOException {
        // 1. 创建SqlSessionFactoryBuilder对象
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        // 2. 加载SqlMapConfig.xml配置文件
        InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml.bak");
        // 3. 创建SqlSessionFactory对象
        SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
        // 4. 获取SqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();
        // 5. 执行SqlSession对象执行查询,获取结果User
        AccountDao accountDao = sqlSession.getMapper(AccountDao.class);

        Account ac = accountDao.findById(1);
        System.out.println(ac);

        // 6. 释放资源
        sqlSession.close();
    }
}

运行程序

正式整合!

项目中导入整合需要的jar包

    <!--Spring操作数据库需要该jar包-->
    </dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>5.2.10.RELEASE</version>
    </dependency>
    <dependency>
    <!--Spring与Mybatis整合的jar包
    这个jar包mybatis在前面,是Mybatis提供的-->
    <groupId>org.mybatis</groupId>
    <artifactId>**mybatis-spring**</artifactId>
    <version>1.3.0</version>
    </dependency>

创建Spring的主配置类

//配置类注解
@Configuration
//包扫描,主要扫描的是项目中的AccountServiceImpl类【有注解@Service】
@ComponentScan("com.itheima")
public class SpringConfig {
}

创建数据源的配置类**

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
    public DataSource dataSource(){
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName(driver);
        ds.setUrl(url);
        ds.setUsername(userName);
        ds.setPassword(password);
        return ds;
    }
}

创建Mybatis配置类并配置SqlSessionFactory**

— 代替Mybatis核心配置文件

    public class MybatisConfig {
    //定义bean,SqlSessionFactoryBean,用于产生SqlSessionFactory对象
    @Bean
    //引用注解 -- 直接在函数参数那放一个
    public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource){
        SqlSessionFactoryBean ssfb = new SqlSessionFactoryBean();
        //设置模型类的别名扫描
        ssfb.setTypeAliasesPackage("com.itheima.domain");
        //设置数据源
        ssfb.setDataSource(dataSource);
        return ssfb;
        }
        //定义bean,返回MapperScannerConfigurer对象
        @Bean
        public MapperScannerConfigurer mapperScannerConfigurer(){
        MapperScannerConfigurer msc = new MapperScannerConfigurer();
        msc.setBasePackage("com.itheima.dao");
        return msc;
        }
    }

主配置类中读properties并引入数据源配置类、Mybatis配置类

    @Configuration
    @ComponentScan("com.itheima")
    **@PropertySource("classpath:jdbc.properties")
    @Import({JdbcConfig.class,MybatisConfig.class})**
    public class SpringConfig {
    }

最后更新于