SpringIOC

目录

Spring框架的概述

Spring框架的优点

Spring的IOC核心技术

IOC的入门程序

导入依赖

编写接口与实现类

编写applicationContext.xml配置文件

编写测试方法

DI注入

构建实体类

编写配置文件

使用set方法

使用构造器

数组,集合和Properties的注入

实体类

xml配置文件

多配置文件

Spring框架开发方式

创建maven工程,导入开发的jar包

创建数据库,创建表结构

编写JavaBean的类

编写AccountDao的接口和实现类

编写配置文件

编程测试程序

IOC注解的方式

半注解

类中标注

编写配置文件

依赖注入常用的注解

例子

测试

纯注解

测试

Spring框架整合JUnit单元测试

导入依赖

测试


Spring框架的概述

Spring的核心是控制反转(IoC控制反转)和面向切面(AOP)。简单来说,Spring是一个分层的JavaSE/EEfull-stack(一站式) 轻量级开源框架。

Spring框架的优点

1.方便解耦,简化开发,Spring就是一个大工厂,可以将所有对象创建和依赖关系维护,交给Spring管理。IOC的作用。

2.AOP编程的支持,Spring提供面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等功能。(可扩展性)

3.声明式事务的支持,只需要通过配置就可以完成对事务的管理,而无需手动编程。

4.方便程序的测试,SpringJunit4支持,可以通过注解方便的测试Spring程序。

5.方便集成各种优秀框架,Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如:Struts2HibernateMyBatisQuartz等)的直接支持。

6.降低JavaEE API的使用难度,Spring JavaEE开发中非常难用的一些APIJDBCJavaMail、远程调用等),都提供了封装,使这些API应用难度大大降低。

SpringIOC核心技术

IOC -- Inverse of Control,控制反转,将对象的创建权力反转给Spring框架!!也就是在使用对象前不用再使用“new”来创建一个对象。

使用IOC可以解决的程序耦合性高的问题。就像去买东西,假设你需要去服装店买衣服,去鞋店买鞋,你需要去两次,但现在有一家店,这家店衣服和鞋都有,你只需要去这一家店就够了。之前新建不同对象需要不同的“new”出来,现在只需要使用spring工厂的getBean一个方法就够了。

IOC的入门程序

导入依赖
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.12</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
编写接口与实现类

public interface UserService {

    public void hello();

}



public class UserServiceImpl implements UserService {
    @Override
    public void hello() {
        System.out.println("Hello IOC!!");
    }
}
编写applicationContext.xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="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">
    
    <!--IOC管理bean-->
    <bean id="userService" class="com.qcbyjy.service.UserServiceImpl" />
    
</beans>

class是你要交给spring管理的类路径;

还有一些其他属性,scope:singleton(单例模式)同容器工厂关闭时销毁 prototype(多例模式)

根据垃圾回收机制来回收;

init-method,bean被载入到容器的时候调用

destroy-method,当bean从容器中删除的时候调用

实例化对象的三种方法:无参数的构造方法(用的最多)、静态工厂实例化、动态工厂实例化

编写测试方法
public class Demo1 {

    /**
     * 入门程序
     */
    @Test
    public void run1(){
        // 使用Spring的工厂
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        // 通过工厂获得类:
        UserService userService = (UserService) applicationContext.getBean("userService");
        userService.hello();
    }

}

DI注入

构建实体类

public class car {
    private int[] name;

    public int[] getName() {
        return name;
    }

    public void setName(int[] name) {
        this.name = name;
    }

    public car() {
    }

    public car(int[] name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "car{" +
                "name=" + Arrays.toString(name) +
                '}';
    }
}

编写配置文件

使用set方法
    <bean id="car" class="com.qcby.service.car">
        <property name="name" value="奔驰"/>
    </bean>
使用构造器
    <bean id="car" class="com.qcby.service.car">
        <constructor-arg name="name" value="奔驰"/>
    </bean>

使用上述方法需要有对应的set方法或构造方法

若注入的属性不是基本类型时需要使用“ref”来替换掉value,同样这个类也需要交给spring来管理。

数组,集合和Properties的注入

实体类
public class CollectionBean {

    // 数组
    private String [] strs;
    public void setStrs(String[] strs) {
        this.strs = strs;
    }

    private List<String> list;
    public void setList(List<String> list) {
        this.list = list;
    }

    private Map<String,String> map;
    public void setMap(Map<String, String> map) {
        this.map = map;
    }

    private Properties properties;
    public void setProperties(Properties properties) {
        this.properties = properties;
    }

    @Override
    public String toString() {
        return "CollectionBean{" +
                "strs=" + Arrays.toString(strs) +
                ", list=" + list +
                ", map=" + map +
                ", properties=" + properties +
                '}';
    }
}
xml配置文件
<!--给集合属性注入值-->
    <bean id="collectionBean" class="com.qcby.demo3.CollectionBean">
        <property name="strs">
            <array>
                <value>美美</value>
                <value>小凤</value>
            </array>
        </property>
        <property name="list">
            <list>
                <value>熊大</value>
                <value>熊二</value>
            </list>
        </property>
        <property name="map">
            <map>
                <entry key="aaa" value="老王"/>
                <entry key="bbb" value="小王"/>
            </map>
        </property>
        <property name="properties">
            <props>
                <prop key="username">root</prop>
                <prop key="password">123456</prop>
            </props>
        </property>
    </bean>

多配置文件

如果有两个或者多个配置文件,有如下两种方式来加载

主配置文件中包含其他的配置文件:
<import resource="applicationContext2.xml"/>



工厂创建的时候直接加载多个配置文件:
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
"applicationContext.xml","applicationContext2.xml");

Spring框架开发方式

  1. 需求:编写servicedao的类,演示代码
  2. 技术选择:持久层使用原始的JDBC的程序,连接池选择的是Druid连接池。

创建maven工程,导入开发的jar

<dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.12</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <!--连接池-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.10</version>
        </dependency>
        <!--mysql驱动包-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.6</version>
        </dependency>
    
    </dependencies>

创建数据库,创建表结构

create database spring_db;
use spring_db;
create table account(
    id int primary key auto_increment,
    name varchar(40),
    money double
)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);

编写JavaBean的类

public class Account implements Serializable {

    private static final long serialVersionUID = 7355810572012650248L;

    private Integer id;
    private String name;
    private Double money;

    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Double getMoney() {
        return money;
    }
    public void setMoney(Double money) {
        this.money = money;
    }

    @Override
    public String toString() {
        return "Account{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", money=" + money +
                '}';
    }
}

编写AccountDao的接口和实现类

public interface AccountDao {

    public List<Account> findAll();

}


public class AccountDaoImpl implements AccountDao {  
 // 注入连接池对象
   private DataSource dataSource;
   public void setDataSource(DataSource dataSource) {
       this.dataSource = dataSource;
   }

   /**
    * 查询所有的数据
    * @return
    */
   @Override
   public List<Account> findAll() {

       /*
       DruidDataSource dataSource = new DruidDataSource();
       dataSource.setDriverClassName("com.mysql.jdbc.Driver");
       dataSource.setUrl("jdbc:mysql:///spring_db");
       dataSource.setUsername("root");
       dataSource.setPassword("root");
       */

       List<Account> list = new ArrayList<>();

       Connection connection = null;
       PreparedStatement stmt = null;
       ResultSet rs = null;

       try {
           // 获取连接
           connection = dataSource.getConnection();
           // 编写sql语句
           String sql = "select * from account";
           // 预编译
           stmt = connection.prepareStatement(sql);
           // 查询
           rs = stmt.executeQuery();
           // 遍历,封装数据
           while (rs.next()){
               Account account = new Account();
               account.setId(rs.getInt("id"));
               account.setName(rs.getString("name"));
               account.setMoney(rs.getDouble("money"));
               list.add(account);
           }
       } catch (SQLException e) {
           e.printStackTrace();
       }finally {
           try {
               connection.close();
           } catch (SQLException e) {
               e.printStackTrace();
           }
           try {
               stmt.close();
           } catch (SQLException e) {
               e.printStackTrace();
           }
           try {
               rs.close();
           } catch (SQLException e) {
               e.printStackTrace();
           }
       }
       return list;
   } 
 }

编写AccountService的接口和实现类

public interface AccountService {

       public List<Account> findAll();

}


public class AccountServiceImpl implements AccountService {

       // 依赖注入
       private AccountDao accountDao;
       public void setAccountDao(AccountDao accountDao) {
           this.accountDao = accountDao;
       }

       /**
        * 查询所有的数据
        * @return
        */
       @Override
       public List<Account> findAll() {
           return accountDao.findAll();
       }

}

编写配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="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">

    <!--配置连接池-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql:///spring_db" />
        <property name="username" value="root" />
        <property name="password" value="root" />
    </bean>

    <!--管理bean-->
    <bean id="accountService" class="com.qcbyjy.service.AccountServiceImpl">
        <property name="accountDao" ref="accountDao" />
    </bean>
    <bean id="accountDao" class="com.qcbyjy.dao.AccountDaoImpl">
        <property name="dataSource" ref="dataSource" />
    </bean>

</beans>

编程测试程序

public class Demo1 {

    @Test
    public void run1(){
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        AccountService accountService = (AccountService) ac.getBean("accountService");
        // 调用方法
        List<Account> list = accountService.findAll();
        for (Account account : list) {
            System.out.println(account);
        }
    }

}

IOC注解的方式

半注解

类中标注

 @Component普通类通用
 @Controller表现层
 @Service业务层
 @Repository持久

若()中value没有明确给出,则默认为首字母小写的类名,即UserService为userService。

编写配置文件
    <!--开启注解扫描 com.qcbyjy.所有的包中的所有的类 -->
    <context:component-scan base-package="com.qcby" />
依赖注入常用的注解

​ @Value 用于注入普通类型(Stringintdouble等类型)

​ @Autowired 默认按类型进行自动装配(引用类型)

​ @Qualifier @Autowired一起使用,强制使用名称注入

​ @Resource Java提供的注解,也被支持。使用name属性,按名称注入对象生命周期(作用范围)

​ @Scope 生命周期注解,取值singleton(默认值,单实例)和prototype(多例)

初始化方法和销毁方法注解(了解)

​ @PostConstruct 相当于init-method

​ @PreDestroy 相当于destroy-method

例子
@Component(value="person")
public class person {
    @Value("塞恩")
    private String name;
    @Value("22")
    private Integer age;
    @Autowired
    @Qualifier("wife02")
    //@Resource(name = "wife02")
    public wife wife;

    @PostConstruct
    public void init(){
        System.out.println("操作...");
    }

    public person() {
    }

    public person(String name, Integer age,wife wife) {
        this.name = name;
        this.age = age;
        this.wife = wife;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public wife getW() {
        return wife;
    }

    public void setW(wife w) {
        this.wife = w;
    }

    @Override
    public String toString() {
        return "person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", wife=" + wife +
                '}';
    }
}
测试

需要使用@ContextConfiguration来加载配置文件。

@ContextConfiguration(classes = "classpath:applicationContext.xml")  //加载配置文件
public class demo1 {
    @Autowired
    private AccountService accountService;

    @Test
    public void run(){
        List<account> list = accountService.findAll();
        for (account account0 : list) {
            System.out.println(account0);
        }
    }
}

纯注解

纯注解模式就是去掉配置文件,只用注解来完成,虽然不用配置文件,但是需要编写一个配置类。

@Configuration 声明是配置类

@ComponentScan 扫描具体包结构的

@Import注解 Spring的配置文件可以分成多个配置的,编写多个配置类。用于导入其他配置类

@Bean注解 只能写在方法上,表明使用此方法创建一个对象,对象创建完成保存到IOC容器中

// 声明当前类是配置类
@Configuration
// 扫描指定的包结构
@ComponentScan(value = "com.qcby.demo4")
// @ComponentScan(value = {"com.qcby.demo4","com.qcby.demo3"})
// 引入新的配置类
@Import(value = {SpringConfig2.class})
public class SpringConfig {

    /**
     * 创建连接池对象,返回对象,把该方法创建后的对象存入到连接池中,使用@Bean注解解决
     */
    @Bean(name="dataSource")
    public DataSource createDataSource(){
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql:///spring_db");
        dataSource.setUsername("root");
        dataSource.setPassword("root");
        return dataSource;
    }

}
测试

需要使用需要使用@ContextConfiguration来加载配置文件。

@ContextConfiguration(classes = SpringConfig.class)  //加载配置类
public class demo1 {
    @Autowired
    private AccountService accountService;

    @Test
    public void run(){
        List<account> list = accountService.findAll();
        for (account account0 : list) {
            System.out.println(account0);
        }
    }
}

Spring框架整合JUnit单元测试

每次进行单元测试的时候,都需要编写创建工厂,加载配置文件等代码,比较繁琐。Spring提供了整合Junit单元测试的技术,可以简化测试开发。

导入依赖

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>5.0.2.RELEASE</version>
            <scope>test</scope>
        </dependency>

测试

@RunWith(value = SpringJUnit4ClassRunner.class)声明为测试单元

@RunWith(value = SpringJUnit4ClassRunner.class)---加入测试单元
//ContextConfiguration(classes = "classpath:applicationContext.xml")  //加载配置文件
@ContextConfiguration(classes = SpringConfig.class)  //加载配置类
public class demo1 {
    @Autowired
    private AccountService accountService;

    @Test
    public void run(){
        List<account> list = accountService.findAll();
        for (account account0 : list) {
            System.out.println(account0);
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值