基于 ssm + maven + redis 使用自定义注解 利用aop基于AspectJ方式 实现redis缓存

  如何能更简洁的利用aop实现redis缓存,话不多说,上demo

  需求:
    数据查询时每次都需要从数据库查询数据,数据库压力很大,查询速度慢,
    因此设置缓存层,查询数据时先从redis中查询,如果查询不到,则到数据库中查询
    然后将数据库中查询的数据放到redis中一份,下次查询时就能直接从redis中查到,不需要查询数据库了

  实现过程:

      先搭建ssm的架子,引入redis,编写redis 缓存方法 RedisCache.java以及序列化用到的工具类

      自定义注解 getCache 目的:
            被这个注解标记的方法实现aop
            防止redis key重复

     编写切面
      @Aspect

        @Pointcut("@annotation(com.spring_redis.cache.GetCache)")
        切入点为自定义注解 即每个被该注解标记的方法实现通知

        @Around("getCache()")
        利用环绕通知
          过程: 查询时,先查询redis 如果存在key-value,则返回不查询
          如果不存在,则查询数据库,之后将查询到的数据存入到redis缓存中
          redis key格式:为了防止key冲突,创建的key格式为:
          包名.类名.方法名.参数类型.参数值",类似 "your.package.SomeService.getById(integer).123"

  目录结构

      

  maven依赖:

    

  1 <properties>
  2             <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  3              <!-- spring版本号 -->
  4             <spring.version>4.0.6.RELEASE</spring.version>
  5             <!-- mybatis版本号 -->
  6             <mybatis.version>3.2.7</mybatis.version>
  7         </properties>
  8   <dependencies>
  9
 10           <!-- spring核心包 -->
 11         <!-- springframe start -->
 12         <dependency>
 13             <groupId>org.springframework</groupId>
 14             <artifactId>spring-core</artifactId>
 15             <version>${spring.version}</version>
 16         </dependency>
 17
 18         <dependency>
 19             <groupId>org.springframework</groupId>
 20             <artifactId>spring-web</artifactId>
 21             <version>${spring.version}</version>
 22         </dependency>
 23
 24         <dependency>
 25             <groupId>org.springframework</groupId>
 26             <artifactId>spring-oxm</artifactId>
 27             <version>${spring.version}</version>
 28         </dependency>
 29
 30         <dependency>
 31             <groupId>org.springframework</groupId>
 32             <artifactId>spring-tx</artifactId>
 33             <version>${spring.version}</version>
 34         </dependency>
 35
 36         <dependency>
 37             <groupId>org.springframework</groupId>
 38             <artifactId>spring-aop</artifactId>
 39             <version>${spring.version}</version>
 40         </dependency>
 41
 42         <dependency>
 43             <groupId>org.springframework</groupId>
 44             <artifactId>spring-jdbc</artifactId>
 45             <version>${spring.version}</version>
 46         </dependency>
 47
 48         <dependency>
 49             <groupId>org.springframework</groupId>
 50             <artifactId>spring-webmvc</artifactId>
 51             <version>${spring.version}</version>
 52         </dependency>
 53
 54         <!-- https://mvnrepository.com/artifact/org.springframework/spring-context-support -->
 55         <dependency>
 56             <groupId>org.springframework</groupId>
 57             <artifactId>spring-context-support</artifactId>
 58             <version>4.0.6.RELEASE</version>
 59         </dependency>
 60
 61         <dependency>
 62             <groupId>org.springframework</groupId>
 63             <artifactId>spring-context</artifactId>
 64             <exclusions>
 65                 <exclusion>
 66                     <groupId>commons-logging</groupId>
 67                     <artifactId>commons-logging</artifactId>
 68                 </exclusion>
 69             </exclusions>
 70             <version>${spring.version}</version>
 71         </dependency>
 72         <dependency>
 73             <groupId>org.springframework</groupId>
 74             <artifactId>spring-test</artifactId>
 75             <version>${spring.version}</version>
 76         </dependency>
 77         <!-- springframe end -->
 78
 79           <!-- aop注解  -->
 80
 81         <dependency>
 82             <groupId>org.aspectj</groupId>
 83             <artifactId>aspectjrt</artifactId>
 84             <version>1.6.12</version>
 85         </dependency>
 86         <dependency>
 87             <groupId>org.aspectj</groupId>
 88             <artifactId>aspectjweaver</artifactId>
 89             <version>1.6.12</version>
 90         </dependency>
 91         <dependency>
 92             <groupId>cglib</groupId>
 93             <artifactId>cglib</artifactId>
 94             <version>2.2</version>
 95         </dependency>
 96
 97           <!-- mysql驱动包 -->
 98         <dependency>
 99             <groupId>mysql</groupId>
100             <artifactId>mysql-connector-java</artifactId>
101             <version>5.1.31</version>
102         </dependency>
103
104           <!-- dbcp2连接池 -->
105         <dependency>
106             <groupId>org.apache.commons</groupId>
107             <artifactId>commons-dbcp2</artifactId>
108             <version>2.0.1</version>
109         </dependency>
110
111         <!-- json数据 -->
112         <dependency>
113             <groupId>org.codehaus.jackson</groupId>
114             <artifactId>jackson-mapper-asl</artifactId>
115             <version>1.9.13</version>
116         </dependency>
117
118           <!-- mybatis核心包 -->
119         <dependency>
120             <groupId>org.mybatis</groupId>
121             <artifactId>mybatis</artifactId>
122             <version>${mybatis.version}</version>
123         </dependency>
124         <!-- mybatis/spring包 -->
125         <dependency>
126             <groupId>org.mybatis</groupId>
127             <artifactId>mybatis-spring</artifactId>
128             <version>1.2.2</version>
129         </dependency>
130
131           <dependency>
132             <groupId>org.springframework.data</groupId>
133             <artifactId>spring-data-redis</artifactId>
134             <version>1.6.1.RELEASE</version>
135         </dependency>
136          <dependency>
137             <groupId>redis.clients</groupId>
138             <artifactId>jedis</artifactId>
139             <version>2.7.3</version>
140         </dependency>
141
142           <!-- servlet-api -->
143         <dependency>
144             <groupId>javax.servlet</groupId>
145             <artifactId>javax.servlet-api</artifactId>
146             <version>3.0.1</version>
147             <scope>provided</scope>
148         </dependency>
149         <dependency>
150             <groupId>javax.servlet.jsp</groupId>
151             <artifactId>jsp-api</artifactId>
152             <version>2.2</version>
153             <scope>provided</scope>
154         </dependency>
155         <!-- servlet-api end -->
156
157           <dependency>
158             <groupId>log4j</groupId>
159             <artifactId>log4j</artifactId>
160             <version>1.2.17</version>
161         </dependency>
162   </dependencies>
163   

  这里只给出redis 的相关配置

    在applicationContext-dao.xml 里添加

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
 4     xmlns:context="http://www.springframework.org/schema/context"
 5     xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
 6     xmlns:util="http://www.springframework.org/schema/util"
 7     xsi:schemaLocation="http://www.springframework.org/schema/beans
 8     http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
 9     http://www.springframework.org/schema/context
10     http://www.springframework.org/schema/context/spring-context-3.2.xsd
11     http://www.springframework.org/schema/tx
12     http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
13     http://www.springframework.org/schema/aop
14     http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
15     http://www.springframework.org/schema/util
16     http://www.springframework.org/schema/util/spring-util-3.2.xsd">
17
18
19         <!-- 加载db.properties文件中的内容,db.properties文件中key命名要有一定的特殊规则 -->
20         <context:property-placeholder location="classpath:properties/db.properties" />
21
22
23
24         <!-- 配置数据源 ,dbcp -->
25
26         <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
27         <property name="driverClassName" value="${jdbc.driver}" />
28         <property name="url" value="${jdbc.url}" />
29         <property name="username" value="${jdbc.username}" />
30         <property name="password" value="${jdbc.password}" />
31         </bean>
32
33
34         <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"
35         p:dataSource-ref="dataSource" p:configLocation="classpath:mybatis/sqlMapConfig.xml"
36         ></bean>
37               <!-- Redis和缓存配置开始 -->
38             <!-- jedis 配置 -->
39             <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig" >
40                   <property name="maxIdle" value="100" />
41                   <property name="maxWaitMillis" value="1000" />
42                   <property name="testOnBorrow" value="true" />
43             </bean >
44
45             <!-- redis连接池 -->
46                 <bean id="jedisPool" class="redis.clients.jedis.JedisPool" destroy-method="close">
47                     <constructor-arg name="poolConfig" ref="poolConfig"/>
48                     <constructor-arg name="host" value="127.0.0.1"/>
49                     <constructor-arg name="port" value="6379"/>
50                 </bean>
51
52               <!-- redis服务器中心 -->
53             <bean id="connectionFactory"  class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" >
54                   <property name="poolConfig" ref="poolConfig" />
55                   <property name="port" value="6379" />
56                   <property name="hostName" value="127.0.0.1" />
57                   <!-- <property name="password" value="${redis.password}" /> -->
58                   <property name="timeout" value="10000" ></property>
59             </bean >
60             <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate" >
61                   <property name="connectionFactory" ref="connectionFactory" />
62                   <property name="keySerializer" >
63                       <bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />
64                   </property>
65                   <property name="valueSerializer" >
66                       <bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />
67                   </property>
68             </bean >
69
70
71
72
73
74             <!-- cache配置 -->
75             <bean id="putCache" class="com.spring_redis.cache.PutCacheAOP" >
76                   <property name="redisTemplate" ref="redisTemplate" />
77             </bean>
78
79             <!-- cache配置 -->
80              <bean id="getCache" class="com.spring_redis.cache.GetCacheAOP" >
81                    <property name="redisTemplate" ref="redisTemplate" />
82              </bean>
83
84              <!-- Redis和缓存配置结束 -->
85
86             <!-- mapper扫描器 -->
87             <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
88                 <!-- 扫描包路径,如果需要扫描多个包,中间使用半角逗号隔开 -->
89                 <property name="basePackage" value="com.spring_redis.mapper"></property>
90                 <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
91             </bean>
92
93             <bean id="roomservice" class="com.spring_redis.service.impl.RoomServiceImpl" >
94
95              </bean>
96
97 </beans>

  springmvc.xml

 1 <beans xmlns="http://www.springframework.org/schema/beans"
 2     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
 3     xmlns:context="http://www.springframework.org/schema/context"
 4     xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
 5     xsi:schemaLocation="http://www.springframework.org/schema/beans
 6         http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
 7         http://www.springframework.org/schema/mvc
 8         http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
 9         http://www.springframework.org/schema/context
10         http://www.springframework.org/schema/context/spring-context-3.2.xsd
11         http://www.springframework.org/schema/aop
12         http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
13         http://www.springframework.org/schema/tx
14         http://www.springframework.org/schema/tx/spring-tx-3.2.xsd ">
15
16     <aop:aspectj-autoproxy proxy-target-class="true"/>
17
18     <!-- 可以扫描controller、service、... 这里让扫描controller,指定controller的包 com.ssm.controlle -->
19     <context:component-scan base-package="com.spring_redis">
20     </context:component-scan>
21     <!-- 使用 mvc:annotation-driven代替上边注解映射器和注解适配器配置 mvc:annotation-driven默认加载很多的参数绑定方法 -->
22     <mvc:annotation-driven />
23     <!-- 视图解析器 解析jsp解析,默认使用jstl标签,classpath下的得有jstl的包 -->
24     <bean
25         class="org.springframework.web.servlet.view.InternalResourceViewResolver">
26         <!-- 配置jsp路径的前缀 <property name="prefix" value="/jsp/"/> -->
27         <!-- 配置jsp路径的后缀 -->
28         <property name="suffix" value=".jsp" />
29     </bean>
30
31
32 </beans>

<aop:aspectj-autoproxy proxy-target-class="true"/>  开启注解这个一定要写到springmvc.xml里,否则注解会不起作用

  那重点开始了

  创建自定义注解

 1 /**
 2  * 自定义注解,对于查询使用缓存的方法加入该注解
 3  * @author Chenth
 4  */
 5 @Retention(RetentionPolicy.RUNTIME)
 6 @Target({ElementType.METHOD})
 7 public @interface GetCache {
 8     String name() default "";
 9     String value() default "";
10 }   

  被这个自定义注解所标记的方法将实现下面的切面

  配置切面

  1 package com.spring_redis.cache;
  2
  3 import java.io.Serializable;
  4 import java.lang.reflect.Method;
  5
  6
  7 import org.aspectj.lang.JoinPoint;
  8 import org.aspectj.lang.ProceedingJoinPoint;
  9 import org.aspectj.lang.annotation.Around;
 10 import org.aspectj.lang.annotation.Aspect;
 11 import org.aspectj.lang.annotation.Pointcut;
 12 import org.aspectj.lang.reflect.MethodSignature;
 13 import org.springframework.beans.factory.annotation.Autowired;
 14 import org.springframework.data.redis.core.RedisTemplate;
 15 import org.springframework.stereotype.Component;
 16
 17 import com.spring_redis.util.RedisCache;
 18
 19 @Component
 20 @Aspect
 21 public class GetCacheAOP  {
 22
 23     @Autowired
 24     private RedisTemplate<Serializable, Object> redisTemplate;
 25
 26     private RedisCache redisCache = new RedisCache();
 27
 28
 29     @Pointcut("@annotation(com.spring_redis.cache.GetCache)")
 30     public void getCache(){
 31         System.out.println("我是一个切入点");
 32     }
 33
 34     /**
 35      * 在所有标注@getCache的地方切入
 36      * @param joinPoint
 37      */
 38     @Around("getCache()")
 39     public Object beforeExec(ProceedingJoinPoint joinPoint){
 40
 41
 42         //前置:到redis中查询缓存
 43         System.out.println("调用从redis中查询的方法...");
 44
 45         //redis中key格式:    id
 46         String redisKey = getCacheKey(joinPoint);
 47
 48         //获取从redis中查询到的对象
 49         Object objectFromRedis = redisCache.getDataFromRedis(redisKey);
 50
 51         //如果查询到了
 52         if(null != objectFromRedis){
 53             System.out.println("从redis中查询到了数据...不需要查询数据库");
 54             return objectFromRedis;
 55         }
 56
 57         System.out.println("没有从redis中查到数据...");
 58
 59         //没有查到,那么查询数据库
 60         Object object = null;
 61         try {
 62             object = joinPoint.proceed();
 63         } catch (Throwable e) {
 64
 65             e.printStackTrace();
 66         }
 67
 68         System.out.println("从数据库中查询的数据...");
 69
 70         //后置:将数据库中查询的数据放到redis中
 71         System.out.println("调用把数据库查询的数据存储到redis中的方法...");
 72
 73         redisCache.setDataToRedis(redisKey, object);
 74         System.out.println("redis中的数据..."+object.toString());
 75         //将查询到的数据返回
 76         return object;
 77     }
 78
 79     /**
 80      * 根据类名、方法名和参数值获取唯一的缓存键
 81      * @return 格式为 "包名.类名.方法名.参数类型.参数值",类似 "your.package.SomeService.getById(int).123"
 82      */
 83
 84     @SuppressWarnings("unused")
 85     private String getCacheKey(ProceedingJoinPoint joinPoint) {
 86
 87
 88         MethodSignature ms=(MethodSignature) joinPoint.getSignature();
 89         Method method=ms.getMethod();
 90         String ActionName = method.getAnnotation(GetCache.class).name();
 91         String fieldList = method.getAnnotation(GetCache.class).value();
 92         //System.out.println("签名是"+ms.toString());
 93         for (String field:fieldList.split(","))
 94              ActionName +="."+field;
 95
 96         //先获取目标方法参数
 97         String id = null;
 98         Object[] args = joinPoint.getArgs();
 99         if (args != null && args.length > 0) {
100             id = String.valueOf(args[0]);
101         }
102
103         ActionName += "="+id;
104         String redisKey = ms+"."+ActionName;
105         return redisKey;
106     }
107
108
109     public void setRedisTemplate(
110             RedisTemplate<Serializable, Object> redisTemplate) {
111         this.redisTemplate = redisTemplate;
112     }
113 }  

  

 @Pointcut("@annotation(com.spring_redis.cache.GetCache)") 这个切入点的作用是
                                      在所有标注@getCache的地方切入 
 @Around("getCache()")这里用的是后置通知,即查询之前先查询redis,如果有数据就返回数据,没有就穿透的数据库查询数据,之后再缓存到redis中

  这里并没有太多的讲解配置ssm框架,可能后续会写关于spring+springmvc+mybatis的框架整合

  编写mapper层,service层,controller层

  mapper

/*** * @author     cmy* @date     2016-10-22* @description 持久化*/public interface RoomMapper {@Insert("insert into room(roomName,address) values(#{roomName},#{addRess})")int insert(Room room);@Select("select * from room where id=#{id}")public Room selectByPrimaryKey(@Param("id")Integer id);}

  service

 1 /**
 2  *
 3  * @author     cmy
 4  * @date     2016-10-22
 5  * @description test
 6  */
 7 public interface RoomService {
 8
 9
10     int insert(Room room)throws Exception;
11
12
13     Room selectByPrimaryKey(Integer id)throws Exception;
14
15 }
16
17 // 实现
18 /**
19  * @author         cmy
20  * @date         2016-10-22
21  * @description  test 实现
22  */
23 public class RoomServiceImpl implements RoomService{
24
25     @Autowired
26     private RoomMapper mapper;
27
28     @Override
29     public int insert(Room room) throws Exception {
30
31         return mapper.insert(room);
32     }
33
34     @Override
35     public Room selectByPrimaryKey(Integer id) throws Exception {
36
37         return mapper.selectByPrimaryKey(id);
38     }
39
40
41 }

   controller

/*** * @author     cmy* @date     2016-10-22* @description test controller*/@Controller
@RequestMapping("room")
public class RoomController {@Autowiredprivate RoomService  roomService;@GetCache(name="room",value="id")@RequestMapping("selectByPrimaryKey")public @ResponseBody Object roomList(Integer id) throws Exception{  System.out.println("已查询到数据,准备缓存到redis...  "+roomService.selectByPrimaryKey(id).getRoomName());return roomService.selectByPrimaryKey(id);}}

  缓存要用到的工具类  RedisCache

 1 public class RedisCache {
 2
 3     @Autowired
 4     private JedisPool jedisPool = new JedisPool();
 5
 6
 7     //从redis缓存中查询,反序列化
 8     public Object getDataFromRedis(String redisKey){
 9         //查询
10         Jedis jedis = jedisPool.getResource();
11         byte[] result = jedis.get(redisKey.getBytes());
12
13         //如果查询没有为空
14         if(null == result){
15             return null;
16         }
17
18         //查询到了,反序列化
19         return SerializeUtil.unSerialize(result);
20     }
21
22     //将数据库中查询到的数据放入redis
23     public void setDataToRedis(String redisKey, Object obj){
24
25         //序列化
26         byte[] bytes = SerializeUtil.serialize(obj);
27
28         //存入redis
29         Jedis jedis = jedisPool.getResource();
30         String success = jedis.set(redisKey.getBytes(), bytes);
31
32         if("OK".equals(success)){
33             System.out.println("数据成功保存到redis...");
34         }
35     }
36 }

  缓存要用到的序列化和反序列化工具

 1 /**
 2  *
 3  * @Description: 序列化反序列化工具
 4  */
 5 public class SerializeUtil {
 6     /**
 7      *
 8      * 序列化
 9      */
10     public static byte[] serialize(Object obj){
11
12         ObjectOutputStream oos = null;
13         ByteArrayOutputStream baos = null;
14
15         try {
16             //序列化
17             baos = new ByteArrayOutputStream();
18             oos = new ObjectOutputStream(baos);
19
20             oos.writeObject(obj);
21             byte[] byteArray = baos.toByteArray();
22             return byteArray;
23
24         } catch (IOException e) {
25             e.printStackTrace();
26         }
27         return null;
28     }
29
30     /**
31      *
32      * 反序列化
33      * @param bytes
34      * @return
35      */
36     public static Object unSerialize(byte[] bytes){
37
38         ByteArrayInputStream bais = null;
39
40         try {
41             //反序列化为对象
42             bais = new ByteArrayInputStream(bytes);
43             ObjectInputStream ois = new ObjectInputStream(bais);
44             return ois.readObject();
45
46         } catch (Exception e) {
47             e.printStackTrace();
48         }
49         return null;
50     }
51 }

 以上就是利用aop+自定义注解实现 redis缓存的过程了

      有不对之处,还望指出 欢迎留言

有参考到的文章:http://www.cnblogs.com/mrlinfeng/p/5857775.html

        http://blog.csdn.net/chentian610/article/details/51012789

转载于:https://www.cnblogs.com/cmyxn/p/5990974.html

ssm+redis 如何更简洁的利用自定义注解+AOP实现redis缓存相关推荐

  1. Springboot整合多数据源(自定义注解+aop切面实现)

    原理: 通过后台配置多个数据源,自定义注解,通过aop配置注解切面,前端调用需要传递数据源参数,根据判断数据源参数,调用相应的service或mapper方法. 实现: 准备俩个数据库:俩张表 表sq ...

  2. SpringBoot自定义注解+AOP+redis实现防接口幂等性重复提交,从概念到实战

    一.前言 在面试中,经常会有一道经典面试题,那就是:怎么防止接口重复提交? 小编也是背过的,好几种方式,但是一直没有实战过,做多了管理系统,发现这个事情真的没有过多的重视. 最近在测试过程中,发现了多 ...

  3. 如何利用自定义注解放行 Spring Security 项目的接口

    在实际项目中使用到了springsecurity作为安全框架,我们会遇到需要放行一些接口,使其能匿名访问的业务需求.但是每当需要当需要放行时,都需要在security的配置类中进行修改,感觉非常的不优 ...

  4. 利用自定义注解实现权限验证

    思路: 根据自定义注解,给对应权限能够查看到的资源的Controller方法上添加注解(也就是一个权限字符串),权限字符串跟方法是一对多的关系,同一个权限字符串可以添加到多个方法上:当用户有对应的权限 ...

  5. SpringBoot 自定义注解+AOP+Redis 防止接口重复提交表单数据

    SpringBoot结合Redis处理重复提交 数据重复提交导致多次请求服务.入库,产生脏数据.冗余数据等情况.禁止重复提交使我们保证数据准确性及安全性的必要操作. 实际上,造成这种情况的场景不少: ...

  6. SpringBoot中利用自定义注解优雅地实现隐私数据脱敏(加密显示)

    前言 这两天在整改等保测出的问题,里面有一个"用户信息泄露"的风险项(就是后台系统里用户的一些隐私数据直接明文显示了),其实指的就是要做数据脱敏. 数据脱敏:把系统里的一些敏感数据 ...

  7. 实现权限控制_Spring自定义注解+AOP实现权限控制

    本文转载于 SegmentFault 社区 作者:锦城 前言 作业系统在测试过程中出现了学生修改路由可以到达教师界面并且可以使用教师功能的问题,学生不用任何工具就可以修改自己的成绩,真的挺要命的,这就 ...

  8. 自定义注解,aop实现注解锁

    多线程环境下,会出现线程不安全的问题,所以要对某些方法加锁以保证线程安全 但是如果方法过多,每个方法前后都加这么一句,有点麻烦了,而且代码可读性也会差一些.可以使用aop切面编程,对某些加有特定注解( ...

  9. java 自定义注解+AOP实现日志记录

    ssm版本: 1.首先自定义一个注解,该注解有两个属性,一个是模块名,一个是操作的内容.该注解是用来修饰Service层中的方法的. 2.创建一个切面类,该切面使用@Aspect和@Component ...

最新文章

  1. Zepto.js库touch模块代码解析
  2. LeetCode 657 : Robot Return to Origin
  3. ASP.NET 2.0 - 如何把上传的文件保存到数据库字段 (转自章立民CnBlogs)
  4. 前端学习笔记2017.6.21-引入JS文件的方法
  5. 细胞分裂java移植_胚胎移植前,先调理好你的子宫内膜!
  6. 浅谈PopupWindow弹出菜单
  7. WebService简单示例
  8. LeetCode 1167. 连接棒材的最低费用(优先队列+贪心)
  9. 关于NSIS脚本的Demo
  10. 【Angular专题】 (3)装饰器decorator,一块语法糖
  11. 我哥以前是做小本生意的,一年花销除外能存个十二万的样子
  12. 常见移动机器人运动学模型总结(图片版)
  13. 手机怎么快速把jpg图片中的文字提取出来
  14. mysql自增主键批量_Mysql批量插入随机数据改进版_设置表主键为自增,免得主键冲突...
  15. 【超实用的浏览器插件】目前Google Chrome最好用的插件,为什么你还在犹豫不决?
  16. html中半圆怎么写,css怎么写半圆?
  17. alios 系统配置转存到一个头文件
  18. 让dede系统 正文标题以拼音显示的方法
  19. 硬盘显示设备未就绪,要怎么恢复资料
  20. vue3+vite2多页面多路由 注意

热门文章

  1. 如何在 Windows XP Service Pack 2 上启用 SQL Server 连接
  2. 不全屏放映ppt的方法
  3. “成功”没那么有道理
  4. 深入学习heritrix---体系结构(Overview of the crawler)
  5. Spring 2 和 JPA 简介
  6. Linux下安装Nginx详细图解教程
  7. 使用php-amqplib连接rabbitMQ 学习笔记及总结
  8. Drill官网文档翻译六:存储插件的注册
  9. [python基础]关于中文编码和解码那点事儿
  10. html怎么绘制飞线,绘制飞线,echarts迁徙图原理