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 练习ioc 、aop的更多相关文章
-
Spring(二)--IoC&;AOP
IOC 一.IOC概述: 一般指控制反转(inversion of Control),把创建对象的权利交给框架,Ioc容器控制对象,是框架的重要特征,并非是面向对象编程的专用术语.它包括依赖注入(DI ...
-
Spring核心--IOC&;AOP
Ioc(控制反转) 所谓的控制反转就是应用本身不负责依赖对象的创建及维护,依赖对象的创建及维护是由外部容器负责的.这样控制权就由应用转移到了外部容器,控制权的转移就是所谓反转. AOP(面向切面编程) ...
-
spring的IOC和AOP
spring的IOC和AOP 1.解释spring的ioc? 几种注入依赖的方式?spring的优点? IOC你就认为他是一个生产和管理bean的容器就行了,原来需要在调用类中new的东西,现在都是 ...
-
spring的IOC和AOP详细讲解
1.解释spring的ioc? 几种注入依赖的方式?spring的优点? IOC你就认为他是一个生产和管理bean的容器就行了,原来需要在调用类中new的东西,现在都是有这个IOC容器进行产生,同时, ...
-
Spring的IOC和AOP之深剖
今天,既然讲到了Spring 的IOC和AOP,我们就必须要知道 Spring主要是两件事: 1.开发Bean:2.配置Bean.对于Spring框架来说,它要做的,就是根据配置文件来创建bean实例 ...
-
Java Spring的IoC和AOP的知识点速记
Spring简介 Spring解决的最核心的问题就是把对象之间的依赖关系转为用配置文件来管理,这个是通过Spring的依赖注入机制实现的. Spring Bean装配 1. IOC的概念以及在Spri ...
-
Spring框架IOC容器和AOP解析
主要分析点: 一.Spring开源框架的简介 二.Spring下IOC容器和DI(依赖注入Dependency injection) 三.Spring下面向切面编程(AOP)和事务管理配置 一.S ...
-
spring之初识Ioc&;Aop
Spring框架的作用 spring是一个轻量级的企业级框架,提供了ioc容器.Aop实现.dao/orm支持.web集成等功能,目标是使现有的java EE技术更易用,并促进良好的编程习惯. Spr ...
-
Spring中IOC和AOP的详细解释
我们是在使用Spring框架的过程中,其实就是为了使用IOC,依赖注入,和AOP,面向切面编程,这两个是Spring的灵魂. 主要用到的设计模式有工厂模式和代理模式. IOC就是典型的工厂模式,通过s ...
-
spring ioc aop 原理
spring ioc aop 原理 spring ioc aop 的原理 spring的IoC容器是spring的核心,spring AOP是spring框架的重要组成部分. 在传统的程序设计中,当调 ...
随机推荐
-
Atitit qzone qq空间博客自动点赞与评论工具的设计与实现
Atitit qzone qq空间博客自动点赞与评论工具的设计与实现 Qzone发送评论的原理 首先,有个a标签, <a class="c_tx3" href="j ...
-
HD1013Digital Roots
Problem Description The digital root of a positive integer is found by summing the digits of the int ...
-
JavaScript入门(4)
一.JS能做什么? 1.增强页面动态效果(如:下拉菜单.图片轮播.信息滚动等) 2.实现页面与用户之间的实时.动态交互(如:用户注册.登录验证等) 什么是变量?http://www.cnblogs.c ...
-
C# 的sql server like 的参数
//试了多种方式,这样写like的参数才正确 sb.Append(" and a.GOODSID like '%'+@GOODSID+'%'"); list.Add(new Sql ...
-
Unity strip engine code可能会使程序崩溃
最近正在做新大厅的红包推荐口令快速领金币入口拍卖行之类的功能,同事把我的捕鱼整合到他的项目中时出现了闪退的问题,经排查是因为strip engine code选项. Strip engine code ...
-
2个简单实例让你快速理解try-catch的用法
相信在实际项目中,你可能经常会看到类似下面的代码 try { // 尝试执行代码块 } catch(err) { // 捕获错误的代码块 } finally { // 结果如何都会执行的代码块 } 简 ...
-
20165309 2017-2018-2《Java程序设计》课程总结
20165309 2017-2018-2<Java程序设计>课程总结 一.每周作业链接汇总 预备作业1:我期望的师生关系 预备作业2:技能学习经验与C语言 预备作业3:Linux安装及学习 ...
-
python-django rest framework框架
1.API 接口 是什么,干什么用的? API简单的来说就是一个url - http://www.oldboyedu.com/get_user/ - http://www.oldboyedu.com ...
-
EditPlus轻量级编辑器配置常用的语法规则!
打开EditPlus编辑器:工具 ---- 参数设置 ---- 文件 ---- 设置&语法: 先配置简单的CSS语法: 勾选下面的 “自动完成” ,加载对应的ACP文件,配置一些常用的语法: ...
-
nodeJS的了解
JavaScript不仅仅只能运行在浏览器中.任何有JS运行环境(runtime)的地方就可以运行JavaScript. Node.js对Google V8进行了封装. 有了Node.js,JavaS ...