# Spring 练习ioc 、aop

2019-11-12 16:06:56来源:博客园 阅读 ()

新老客户大回馈,云服务器低至5折

# Spring 练习ioc 、aop

Spring 练习

通过学习spring的基础知识,了解了Spring为了降低Java开发的复杂性,采取了以下4种关键策略:

  • 基于POJO的轻量级和最小侵入性编程;
  • 通过依赖注入和面向接口实现松耦合;
  • 基于切面和惯例进行声明式编程;
  • 通过切面和模板减少样板式代码。

下面将做一个spring的练习demo,进一步熟悉spring的ioc和aop的使用方法,以及使用spring模板的优点。

Demo说明

将构建一个用户更删改查的项目,其中对项目进行分层,通过spring的ioc的特性进行依赖注入。并使用aop特性增加日志操作。数据库操作使用了spring的jdbcTemplate简化数据库操作。

项目结构

创建一个maven项目,并构建如下文件夹

--springdemo
    --src
        --main
            --java
                --aop
                --conf
                --dao
                --service
                --entity
            --resources
        --test
            --java
                --service
    pom.xml

使用到的依赖有spring,slf4j,log4j,mysql-connector等。

pom.xml如下:

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.tong</groupId>
  <artifactId>spring-demo</artifactId>
  <version>1.0-SNAPSHOT</version>

  <name>spring-demo</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
      <spring.version>4.3.2.RELEASE</spring.version>
      <slf4j.version>1.7.24</slf4j.version>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <scope>test</scope>
    </dependency>
      <!-- spring 核心 -->
      <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-context</artifactId>
          <version>${spring.version}</version>
      </dependency>
      <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-beans</artifactId>
          <version>${spring.version}</version>
      </dependency>
      <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-core</artifactId>
          <version>${spring.version}</version>
      </dependency>
      <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-context-support</artifactId>
          <version>${spring.version}</version>
      </dependency>
      <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-expression</artifactId>
          <version>${spring.version}</version>
      </dependency>
      <!-- spring aop -->
      <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-aop</artifactId>
          <version>${spring.version}</version>
      </dependency>
      <dependency>
          <groupId>org.aspectj</groupId>
          <artifactId>aspectjweaver</artifactId>
          <version>1.8.8</version>
      </dependency>
      <!-- spring junit -->
      <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-test</artifactId>
          <version>${spring.version}</version>
      </dependency>
      <!-- spring jdbc -->
      <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-jdbc</artifactId>
          <version>${spring.version}</version>
      </dependency>
      <!-- mysql 驱动 -->
      <dependency>
          <groupId>mysql</groupId>
          <artifactId>mysql-connector-java</artifactId>
          <version>5.1.22</version>
      </dependency>
      <!-- slf4j -->
      <dependency>
          <groupId>org.slf4j</groupId>
          <artifactId>slf4j-api</artifactId>
          <version>${slf4j.version}</version>
      </dependency>
      <dependency>
          <groupId>org.slf4j</groupId>
          <artifactId>slf4j-log4j12</artifactId>
          <version>${slf4j.version}</version>
      </dependency>
  </dependencies>

  <build>
    <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
      <plugins>
        <!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.1.0</version>
        </plugin>
        <!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.8.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.22.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-jar-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>2.5.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>2.8.2</version>
        </plugin>
        <!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
        <plugin>
          <artifactId>maven-site-plugin</artifactId>
          <version>3.7.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-project-info-reports-plugin</artifactId>
          <version>3.0.0</version>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>

项目分层说明

entity层

entity层即包含User.jave实体类,是一个POJO类,仅包含属性,构造器和setter,getter方法。

如下:

package com.tong.entity;

/**
 * User实体类
 *
 * @author tongl
 * @version 1.0 11/11/2019
 */
public class User {
    Integer id;
    String name;
    String sex;
    Integer age;

    public User() {
    }

    public User(Integer id, String name, String sex, Integer age) {
        this.id = id;
        this.name = name;
        this.sex = sex;
        this.age = age;
    }

    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 String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public Integer getAge() {
        return age;
    }

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

    @Override
    public String toString() {
        return "User{" + "id=" + this.id + ", name='" + this.name + '\'' + ", sex='" + this.sex + '\'' + ", age=" + this.age + '}';
    }
}

dao层

DAO层主要是做数据持久层的工作,负责与数据库进行联络的一些任务都封装在此,DAO层的设计首先是设计DAO的接口,然后在Spring的配置文件中定义此接口的实现类,然后就可在模块中调用此接口来进行数据业务的处理,而不用关心此接口的具体实现类是哪个类,显得结构非常清晰,DAO层的数据源配置,以及有关数据库连接的参数都在Spring的配置文件中进行配置。

包括接口和实现。

UserDao.java

package com.tong.dao;

import com.tong.entity.User;

/**
 * 持久化数据层接口
 *
 * @author tongl
 */
public interface UserDao {


    /**
     * 新增用户
     *
     * @param user 用户
     */
    void addUser(User user);

    /**
     * 根据id删除用户
     *
     * @param id id
     */
    void deleteUser(int id);

    /**
     * 根据id查找用户
     *
     * @param id 用户id
     */
    User getUser(int id);

    /**
     * 更新用户信息
     *
     * @param user 用户
     */
    void updateUser(User user);


}

UserDaoImpl.java

package com.tong.dao.impl;

import com.tong.dao.UserDao;
import com.tong.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import java.util.List;

/**
 * 持久化数据层实现
 *
 * @author tongl
 */
@Repository
public class UserDaoImpl implements UserDao {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    /**
     * 新增用户
     *
     * @param user 用户
     */
    @Override
    public void addUser(User user) {
        jdbcTemplate.update("insert into t_user values(?,?,?,?)", user.getId(), user.getName(), user.getSex(), user.getAge());
    }

    /**
     * 根据id删除用户
     *
     * @param id id
     */
    @Override
    public void deleteUser(int id) {
        jdbcTemplate.update("delete from t_user where id = ?", id);
    }

    /**
     * 根据id查找用户
     *
     * @param id 用户id
     * @return user
     */
    @Override
    public User getUser(int id) {
        List<User> users = jdbcTemplate.query("select * from t_user where id = ?",
                new BeanPropertyRowMapper<User>(User.class), id);
        if (users != null && users.size() > 0) {
            return users.get(0);
        }
        return null;
    }

    /**
     * 更新用户
     *
     * @param user 用户
     */
    @Override
    public void updateUser(User user) {
        jdbcTemplate.update("update t_user set name = ?, age = ?, sex = ? where id = ?",
                user.getName(), user.getAge(), user.getSex(), user.getId());
    }

}

service层

Service层主要负责业务模块的逻辑应用设计。同样是首先设计接口,再设计其实现的类,接着再Spring的配置文件中配置其实现的关联。这样我们就可以在应用中调用Service接口来进行业务处理。Service层的业务实现,具体要调用到已定义的DAO层的接口,封装Service层的业务逻辑有利于通用的业务逻辑的独立性和重复利用性,程序显得非常简洁。

UserService.java

package com.tong.service;

import com.tong.entity.User;

/**
 * 服务层接口
 *
 * @author tongl
 * @version 1.0 10/10/2019
 */
public interface UserService {

    /**
     * 新增修改用户
     *
     * @param user 用户
     */
    void saveUser(User user);

    /**
     * 删除用户
     *
     * @param id 用户id
     */
    void deleteUser(int id);
}

UserServiceImpl.java

package com.tong.service.impl;

import com.tong.dao.UserDao;
import com.tong.entity.User;
import com.tong.service.UserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * 服务层实现
 *
 * @author tongl
 */
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserDao userDao;

    Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);

    /**
     * 添加修改用户
     *
     * @param user 用户
     */
    @Override
    public void saveUser(User user) {
        Integer id = user.getId();
        User u = userDao.getUser(id);
        if (u == null) {
            // 如果查询user为空,那么新增用户
            userDao.addUser(user);
            logger.info("新增用户:{}", user);
        } else {
            // 如果user不为空,那么更改用户
            userDao.updateUser(user);
            logger.info("修改用户信息:{}", user);
        }
    }

    /**
     * 删除用户
     *
     * @param id 用户id
     */
    @Override
    public void deleteUser(int id) {

        User user = userDao.getUser(id);
        userDao.deleteUser(id);

        logger.info("删除用户:{}", user);
    }

}

aop层

实现日志切面

Log.java

package com.tong.aop;

import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;

/**
 * 日志服务
 *
 * @author tongl
 */
@Component
@ComponentScan(basePackages = {"com.fiberhome"})
@Aspect
@EnableAspectJAutoProxy
public class Log {
    Logger logger = LoggerFactory.getLogger(Log.class);

    /**
     * 配置后置通知:新增/修改用户打印日志
     */
    @AfterReturning("execution(* com.tong.service.*.saveUser(..))")
    public void addLog() {
        logger.info("添加/修改用户操作-日志记录");
    }

    /**
     * 配置后置通知:删除用户打印日志
     */
    @AfterReturning("execution(* com.tong.service.*.deleteUser(..))")
    public void deleteLog() {
        logger.info("删除用户操作-日志记录");
    }
}

config

本项目使用Java配置方式,这里是Java配置文件。

DataConfig.java

package com.tong.conf;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.*;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DriverManagerDataSource;


@Configuration
@ComponentScan(basePackages = {"com.tong"})
@PropertySource(value = "classpath:db.properties")
@Scope("singleton")
public class DataConfig {

    @Value("${jdbc.driver}")
    private String driver;
    @Value("${jdbc.url}")
    private String url;
    @Value("${jdbc.username}")
    private String username;
    @Value("${jdbc.password}")
    private String password;

    /**
     * 创建连接池
     *
     * @return dataSource
     */
    @Bean
    public DataSource dataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName(driver);
        dataSource.setUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        return dataSource;
    }

    @Bean
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
        return new PropertySourcesPlaceholderConfigurer();
    }

    @Bean
    public JdbcTemplate getJdbcTemplate(DataSource dataSource) {
        return new JdbcTemplate(dataSource);
    }

}

测试类

UserServiceTest

package com.tong.service;

import com.tong.conf.DataConfig;
import com.tong.entity.User;
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;


/**
 * 用户服务测试类
 * @author tongl
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {DataConfig.class})
public class UserServiceTest {

    @Autowired
    private UserService userService;

    /**
     * 添加用户测试
     */
    @Test
    public void testAddUser(){
        User user = new User(1001,"张三","男",17);
        User user2 = new User(1001,"张三","男",20);
        User user3 = new User(1012,"张四","男",18);
        //System.out.println(user);
        userService.saveUser(user);
        userService.saveUser(user2);
        userService.saveUser(user3);
    }

    /**
     * 删除用户测试
     */
    @Test
    public void testDeleteUser(){

        userService.deleteUser(1001);
        userService.deleteUser(1002);
    }
}

resources文件

db.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:///user?useUnicode=true&characterEncoding=utf-8
jdbc.username=root
jdbc.password=root

log4j.properties

### 设置###
log4j.rootLogger = info,stdout,D,E

### 输出信息到控制抬 ###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n

### 输出DEBUG 级别以上的日志到logs/debug.log ###
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = logs/debug.log
log4j.appender.D.Append = true
log4j.appender.D.Threshold = DEBUG 
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

### 输出ERROR 级别以上的日志到logs/error.log ###
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File =logs/error.log
log4j.appender.E.Append = true
log4j.appender.E.Threshold = ERROR 
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

源代码

spring-demo


原文链接:https://www.cnblogs.com/leton/p/11845740.html
如有疑问请与原作者联系

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:spring+hibernate配置多数据源

下一篇:Java生鲜电商平台-商家支付系统与对账系统架构实战