4.3-Spring框架——Spring框架简单例子理解控制反转和依赖注入-全注解配置版本

Spring框架简单例子理解控制反转和依赖注入-全注解配置版本

回到第一章:目录


提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

Spring 框架 可以使用xml配置和注解的方式来实现控制反转和依赖注入,使用注解方式更加简洁,避免了大量的xml配置,这节用1个例子工程介绍11个最基础的注解的使用方法。

Spring注解主要是替代xml中的配置,这节仅介绍几个常用的原始注解,下一节介绍新加的几个注解。

@Component ——使用在类上,用于实例化Bean ,
@Controller ——使用在web层类上,用于实例化Bean ,作用和@Component 相同,仅用于区分web层代码,增加可读性。
@Service ——使用在service层类上,用于实例化Bean ,作用和@Component 相同,仅用于区分service层代码,增加可读性。
@Repository——使用在dao层类上,用于实例化Bean ,作用和@Component 相同,仅用于区分dao层代码,增加可读性。
@Autowired ——使用在属性字段上,用于根据类型依赖注入
@Qualifier ——使用在属性字段上,结合@Autowired一起使用用于根据名称进行依赖注入
@Resource —— 使用在属性字段上,相当于@Autowired+@Qualifier,按照名称进行注入
@Value —— 使用在属性字段上,注入普通属性(非对象)
@Scope ——使用在类上,标注Bean的作用范围 ,通常取值为:singleton(单例)或 prototype(多例)
@PostConstruct ——使用在方法上标注该方法是Bean的初始化方法
@PreDestroy ——使用在方法上标注该方法是Bean的销毁方法


提示:以下是本篇文章正文内容,下面案例可供参考

一、仅用原始注解工程示例

工程目录结构:
在这里插入图片描述

1、pom文件

<dependencies>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.32</version>
        </dependency>
        <dependency>
            <groupId>c3p0</groupId>
            <artifactId>c3p0</artifactId>
            <version>0.9.1.2</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.10</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.0.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>5.0.5.RELEASE</version>
        </dependency>
    </dependencies>

2、部分代码说明注解的用法

user.java

//让spring实例化bean对象
@Component("user1")
public class User {
    private String name;
    private int age;
    ...
    }

UserDaoImpl .java

// Repository 注解的作用和Component是一样的,让spring创建对象并加入到spring容器中,只是用于区分这时 dao层的代码。
@Repository("userDao")
//Scope 的作用是告诉spring容器,只生成1个userDao对象(单例)
@Scope("singleton")
public class UserDaoImpl implements UserDao {
    public String save(User user){
        System.out.println("保存完毕:"+user.toString());
        return "保存成功";
    }
    ...
}

UserServiceImpl.java

//@Service("userService") 注解的作用是让spring创建对象并加入到spring容器中。
// 作用和@Component是一样的,只是用于区分这个是service层代码。
// 双引号的 userService 是只创建的对象在容器中的id,便于通过id访问。
//@Component
@Service("userService")
public class UserServiceImpl implements UserService {
    //@Resource(name="userDao") 注解的作用是 依赖注入。从spring容器中获取赋值给userDao对象,赋值给userDao
    //Resource 的作用 等同于  Autowired + Qualifier 注解
    /*@Autowired
@Qualifier("userDao")*/
    @Resource(name="userDao")
    private UserDao userDao;

    @Override
    public String save(User user) {
        // 写业务逻辑
        if(user.getName() == null){
            return "用户名不能为空";
        }
        if(user.getAge() < 0 || user.getAge() > 150){
            return "年龄输入不符合业务要求,应该输入 0-150之间的值。";
        }
        System.out.println("调用DAO层的userDao的save方法保存user对象。");
        return userDao.save(user);
    }

UserController.java

// Controller 注解的作用和Component是一样的,让spring创建对象并加入到spring容器中,只是用于区分这时 Controller 层的代码。
@Controller("userController")
public class UserController {

    //@Resource(name="userService")
    @Autowired
    @Qualifier("userService")
    private UserService userService;

    public String save(User user){
        if(user == null){
            return "保存的user对象不能为空";
        }
        return userService.save(user);
    }

MainApp.java 测试代码。

public class MainApp {

    public static void main(String[] args) throws SQLException {
       // 加载配置文件
        ApplicationContext app  = new ClassPathXmlApplicationContext("applicationContext.xml");
        // 新建user对象
        User user = new User();
        user.setAge(14);
        user.setName("tom");
        // 从spring容器中获取controller对象
        UserController controller = (UserController) app.getBean("userController");
        //调用save方法
        System.out.println(controller.save(user));
        // 从容器中获取user1对象
        User user1 = (User)app.getBean("user1");
        System.out.println(controller.save(user1));
        // c3p0数据源测试...
        //c3p0 数据源
//        DataSource dataSource  =  (DataSource)app.getBean("c3p0DataSource");
//        System.out.println(dataSource.getConnection());
        //druid 数据源测试
        DruidDataSource druidDataSource  =  (DruidDataSource)app.getBean("druidDataSource");
        System.out.println(druidDataSource.getConnection());

    }
}

applicationContext.xml spring 的xml主配置文件。

<!-- 包扫描配置 -->
<context:component-scan base-package="com.xxx"></context:component-scan>

<!-- 配置c3p0数据源 -->
<context:property-placeholder location="classpath:jdbc.properties"/>
<bean id="c3p0DataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    <property name="driverClass" value="${jdbc.driver}"/>
    <property name="jdbcUrl" value="${jdbc.url}"/>
    <property name="user" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.password}"/>
</bean>
<!-- 配置druid数据源 -->
<context:property-placeholder location="classpath:jdbc2.properties"/>
<bean id="druidDataSource" 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>

<!-- 配置 userController -->
<bean id="userController" class="com.xxx.controller.UserController">
    <property name="userService" ref="userService"></property>
</bean>

2 个数据源配置
jdbc.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test
jdbc.username=root
jdbc.password=my@123456

jdbc2.properties

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

二、全注解工程示例

使用spring的新注解,将以上工程的xml配置文件进一步替换:
@Configuration ——使用在类上,用于指定当前类是一个 Spring 的配置类
@ComponentScan —— 使用在类上,用于指定 Spring 在初始化容器时要扫描的包。
作用和在 Spring 的 xml 配置文件中的 <context:component-scan base-package=“xxx”/>一样
@Bean —— 使用在方法上,标注将该方法的返回值存储到 Spring 容器中
@PropertySource —— 使用在类上,用于加载.properties 文件中的配置 ,通常用于加载数据源的配置文件。
@Import —— 使用在类上,用于导入其他配置类

工程目录结构:
在这里插入图片描述

1、在以上工程的基础上,新增了配置类:

C3p0DataSource.java

package com.xxx.configure;

import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.PropertySource;
import java.beans.PropertyVetoException;

@PropertySource("classpath:jdbc.properties")
public class C3p0DataSource {

    @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="c3p0DataSource")
    public javax.sql.DataSource getC3p0DataSource() throws PropertyVetoException, PropertyVetoException {
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setDriverClass(driver);
        dataSource.setJdbcUrl(url);
        dataSource.setUser(username);
        dataSource.setPassword(password);
        return dataSource;
    }
}

DruidDataSource.java

package com.xxx.configure;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.PropertySource;
import java.beans.PropertyVetoException;

@PropertySource("classpath:jdbc2.properties")
public class DruidDataSource {

    @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="druidDataSource")
    public javax.sql.DataSource getDruidDataSource() throws PropertyVetoException, PropertyVetoException {
        com.alibaba.druid.pool.DruidDataSource dataSource = new com.alibaba.druid.pool.DruidDataSource();
        dataSource.setDriverClassName(driver);
        dataSource.setUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        return dataSource;
    }
}

SpringConfiguration.java

package com.xxx.configure;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;


@Configuration
@ComponentScan("com.xxx")
@Import({C3p0DataSource.class,DruidDataSource.class})
public class SpringConfiguration {

}

3、删掉 applicationContext.xml(全部用注解替换掉了)

4、修改测试代码

ApplicationContext 的生成方法,改为从注解加载 spring 上下文。

 public static void main(String[] args) throws SQLException {
       // 加载配置文件,改用从AnnotationConfigApplicationContext类来加载
        ApplicationContext app = new AnnotationConfigApplicationContext(SpringConfiguration.class);
        // 新建user对象
        User user = new User();
        user.setAge(14);
        user.setName("tom");
        // 从spring容器中获取controller对象
        UserController controller = (UserController) app.getBean("userController");
        //调用save方法
        System.out.println(controller.save(user));
        // 从容器中获取user1对象
        User user1 = (User)app.getBean("user1");
        System.out.println(controller.save(user1));
        // c3p0数据源测试...
        //c3p0 数据源
//        DataSource dataSource  =  (DataSource)app.getBean("c3p0DataSource");
//        System.out.println(dataSource.getConnection());
        //druid 数据源测试
        DruidDataSource druidDataSource  =  (DruidDataSource)app.getBean("druidDataSource");
        System.out.println(druidDataSource.getConnection());

    }

完整工程代码:
链接:https://pan.baidu.com/s/1xoanTz39QergtQXWX4Pwzg
提取码:idjs

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值