springAOP

cglib动态代理

(1)pom中添加依赖

<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>2.2.2</version>
</dependency>

(2)
UserDao.class

public class UserDao{
    public void add() {
        System.out.println("UserDao.add([])方法");
    }

}

(3)MyMethodInterceptor.class

package com.tjetc.proxy;

import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

public class MyMethodInterceptor implements MethodInterceptor {
    /**
     *
     * @param proxy 代理对象(子类对象)
     * @param method  被调用的方法
     * @param args  方法的参数数组
     * @param methodProxy method增强,好处:可以提高性能
     * @return 返回值
     * @throws Throwable
     */
    public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        //前置增强
        System.out.println("开启事务");
        //调用目标类的方法
        Object result = methodProxy.invokeSuper(proxy, args);
        //后置增强
        System.out.println("提交事务");
        return result;
    }
}

(4)

package com.tjetc.test;

import com.tjetc.dao.impl.UserDaoImpl;
import com.tjetc.proxy.MyMethodInterceptor;
import net.sf.cglib.proxy.Enhancer;
import org.junit.Test;

public class TestCglibProxy {
    @Test
    public void testAdd(){
            //创建目标类对象
        Object obj = new UserDao();
        //创建Enhancer对象
        Enhancer enhancer = new Enhancer();
        //设置被代理的父类对象类类型
        enhancer.setSuperclass(obj.getClass());
        //设置enhancer对象的属性中间类方法拦截器
        enhancer.setCallback(new MyMethodInterceptor());
        //调用enhancer的create()方法使用字节码技术动态在内存中创建目标类的子类(代理类)对象
        UserDaoImpl proxy = (UserDaoImpl) enhancer.create();
        //调用代理类对象的方法
        proxy.add();;
    }
}

SpringAOP基于XML实现

(1)
导入依赖

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.3.4</version>
</dependency>

<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.9.6</version>
</dependency>

(2)
创建applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans
        xmlns="http://www.springframework.org/schema/beans"
        xmlns:aop="http://www.springframework.org/schema/aop"
        xmlns:context="http://www.springframework.org/schema/context"
       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
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
">

</beans>

(3)

package com.tjetc.aspect;
//切面类
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;

public class TransactionAspect {
    public void doBefore(JoinPoint jp){
        System.out.println("前置增强");
        System.out.println("jp.getTarget() = " + jp.getTarget());
        System.out.println("jp.getArgs() = " + jp.getArgs());
        System.out.println("jp.getSignature() = " + jp.getSignature());
    }

    public void doAfterReturning(){
        System.out.println("后置增强");
    }
    public void doAfter(){
        System.out.println("最终增强");
    }
    public void doAfterThrowing(){
        System.out.println("异常增强");
    }

    public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("环绕前");
        Object result = pjp.proceed();
        System.out.println("环绕后");
        return result;
    }
}

(4)

package com.tjetc.service;


//被代理的目标类
public class PersonService {
    public void add(){
        System.out.println("PersonService.add([])方法");
    }
}

(5)在applicationContext.xml下配置bean节点和切面

    <!--被代理的目标类-->
<bean id="personService" class="com.tjetc.service.PersonService"></bean>
    <!--切面类-->
    <bean id="transactionAspect" class="com.tjetc.aspect.TransactionAspect"></bean>
    <!--配置切面-->
    <aop:config>
        <!--配置在外面的切点,所有切面共享;配置在某个切面内的切点,该切点独享-->

        <!--配置切面-->
        <aop:aspect id="myAspect" ref="transactionAspect">
            <!--配置切点-->
            <aop:pointcut id="myCut" expression="execution(* com.tjetc.service..*.*(..))"></aop:pointcut>
            <!--配置增强:两种模式,一种是前4个;一种是最后一个-->
            <aop:before method="doBefore" pointcut-ref="myCut"></aop:before>
            <aop:after-returning method="doAfterReturning" pointcut-ref="myCut"></aop:after-returning>
            <aop:after method="doAfter" pointcut-ref="myCut"></aop:after>
            <aop:after-throwing method="doAfterThrowing" pointcut-ref="myCut"></aop:after-throwing>
            <aop:around  method="doAround" pointcut-ref="myCut"></aop:around>
        </aop:aspect>
    </aop:config>

(6)

package com.tjetc.test;

import com.tjetc.service.PersonService;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test1 {

    @Test
    public void testAdd(){
            //实例化容器对象
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        //得到代理对象
        PersonService personService = (PersonService) context.getBean("personService");
        System.out.println("personService.getClass() = " + personService.getClass());
        //调用代理对象的方法
        personService.add();
    }
}

日志

----------------日志----------------
(1)在pom.xml文件中加入以下依赖

 <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.3.4</version>
    </dependency>


    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.9.6</version>
    </dependency>

    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.13.2</version>
    </dependency>


    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.17</version>
    </dependency>

(2)applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans
        xmlns="http://www.springframework.org/schema/beans"
        xmlns:aop="http://www.springframework.org/schema/aop"
       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
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
">

</beans>

(3)PersonService.java

package com.tjetc.service;

public class PersonService {
    public void add(){
        System.out.println("PersonService.add([])方法");
    }

    public void update(){
        System.out.println("PersonService.update([])方法");
    }

    
}

(4)log4j.properties

#设置级别和目的地(这里可以设置多个目的地)
log4j.rootLogger=DEBUG,Console,File

#Console  输出到控制台
log4j.appender.Console=org.apache.log4j.ConsoleAppender  
#灵活设置日志格式
log4j.appender.Console.layout=org.apache.log4j.PatternLayout  
#日志输出格式
# %d=datetime日期和时间
# %t=thread
# %-5p -表示左对齐 5代表5个字符 p代表级别
# %c 表示class 哪个类
# %m message
# %n 换行\n的意思

log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n

#输出到文件(一直输出到该文件中)
log4j.appender.File = org.apache.log4j.FileAppender
#输出日志文件路径
log4j.appender.File.File = D:\\log\\JavaBean_log\\File.log
#包含日志产生的时间、线程、类别等等信息 #TTCC T Time Thread C class
log4j.appender.File.layout = org.apache.log4j.TTCCLayout
#日志文件输出格式
log4j.appender.File.layout.ConversionPattern =%d [%t] %-5p [%c] - %m%n

(5)测试类 TestLog4j

package com.tjetc.test;

import org.apache.log4j.Logger;

public class TestLog4j {
    //声明日志对象
    public static Logger logger = Logger.getLogger(TestLog4j.class);

    public static void main(String[] args) {
        //日志的级别从低到高
        //很低的日志级别一般不会使用
        logger.trace("这是trace日志信息");
        //细粒度信息对调试应用非常有帮助,主要打印一些运行信息
        logger.debug("这是debug的日志");
        //粗粒度突出强调应用程序的运行过程,打印感兴趣或者重要的信息
        logger.info("这是info日志信息");
        //表明会出现潜在错误的情形,有些信息不是错误信息,但也要给程序要一点提示
        logger.warn("这是warn日志信息");
        //指出虽然发生错误,但不影响运行,打印错误和异常信息,如果不想输出太多日志可以使用该级别
        logger.error("这是error日志信息");
        //每个严重的错误事件将会导致应用程序的退出,出现错误可以停止程序运行进行调试
        logger.fatal("这是fatal日志信息");

    }
}

(6)制造一个bug
在PersonService的add方法中添加System.out.println(1/0);

   public void add(){
        System.out.println("PersonService.add([])方法");
        System.out.println(1/0);
    }

(7)

package com.tjetc.aspect;

import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.text.SimpleDateFormat;
import java.util.Date;


public class LogAspect {
    private static Logger logger = Logger.getLogger(LogAspect.class);
    public void doBefore(JoinPoint jp){
        logger.info("方法:"+jp.getSignature()+",进入时间:"+ new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS").format(new Date()));
    }
    public void doAfterReturning(JoinPoint jp){
        logger.info("方法:"+jp.getSignature()+",方法返回时间:"+ new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS").format(new Date()));
    }
    public void doAfter(JoinPoint jp){
        logger.info("方法:"+jp.getSignature()+",方法最终离开时间:"+ new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS").format(new Date()));
        
    }
    
    public void doAfterThrowing(JoinPoint jp,Exception ex){
        logger.info("方法:"+jp.getSignature()+",方法发生异常时间:"+ new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS").format(new Date()));
        //在日志记录发生什么异常的详情
        StringWriter stringWriter = new StringWriter();
        //将异常的详细信息写到StringWriter缓存
        ex.printStackTrace(new PrintWriter(stringWriter,true));
        //将StringWriter缓存的日志信息写到日志文件中去
        logger.info(stringWriter.getBuffer().toString());
    }
}

(8)applicationContext中配置节点 切面 切点

<bean id="personService" class="com.tjetc.service.PersonService"></bean>
<!--切面类-->
<bean id="logAspect" class="com.tjetc.aspect.LogAspect"></bean>
<!--aop配置-->
<aop:config>
    <!--配置切面-->
    <aop:aspect id="logAspect" ref="logAspect">
        <!--配置切点-->
        <aop:pointcut id="mycut" expression="execution(* com.tjetc.service..*.*(..))"></aop:pointcut>
        <!--配置增强-->
        <aop:before method="doBefore" pointcut-ref="mycut"></aop:before>
        <aop:after-returning method="doAfterReturning" pointcut-ref="mycut"></aop:after-returning>
        <aop:after method="doAfter" pointcut-ref="mycut"/>
        <aop:after-throwing method="doAfterThrowing" throwing="ex" pointcut-ref="mycut"></aop:after-throwing>
    </aop:aspect>
</aop:config>

(9)测试类TestAopLog

package com.tjetc.test;

import com.tjetc.service.PersonService;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestAopLog {
    @Test
    public void testAdd(){
            //创建容器对象
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        //从容器得到代理对象
        PersonService personService = (PersonService) context.getBean("personService");
        //调用方法
        personService.add();
        personService.update();
    }
}

自动生成

(0)settings-editor-Live Templates-点"+"-Live Template

(1)引入依赖

<dependencies>
    <dependency>
        <groupId>org.mybatis.generator</groupId>
        <artifactId>mybatis-generator-core</artifactId>
        <version>1.4.0</version>
    </dependency>
</dependencies>
<build>
    <plugins>
        <plugin>
            <groupId>org.mybatis.generator</groupId>
            <artifactId>mybatis-generator-maven-plugin</artifactId>
            <version>1.3.6</version>
            <configuration>
                <verbose>true</verbose>
                <overwrite>false</overwrite>
            </configuration>
            <dependencies>
                <dependency>
                    <groupId>mysql</groupId>
                    <artifactId>mysql-connector-java</artifactId>
                    <version>5.1.46</version>
                </dependency>
            </dependencies>
        </plugin>
    </plugins>
</build>

(2)File and Code Templates

generatorConfig.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">

<generatorConfiguration>
    <context id="testTables" targetRuntime="MyBatis3">
        <commentGenerator>
            <!-- 是否去除自动生成的注释 true:是 : false:否 -->
            <property name="suppressAllComments" value="true"/>
        </commentGenerator>
        <!--数据库连接的信息:驱动类、连接地址、用户名、密码 -->
        <jdbcConnection driverClass="com.mysql.jdbc.Driver"
                        connectionURL="jdbc:mysql://localhost:3306/spring0712" userId="root"
                        password="123456">
        </jdbcConnection>
        <!-- 默认false,把JDBC DECIMAL 和 NUMERIC 类型解析为 Integer,为 true时把JDBC DECIMAL 和
                        NUMERIC 类型解析为java.math.BigDecimal -->
        <javaTypeResolver>
            <property name="forceBigDecimals" value="false"/>
        </javaTypeResolver>

        <!-- targetProject:生成PO类的位置 -->
        <javaModelGenerator targetPackage="com.tjetc.domain"
                            targetProject=".\src\main\java">
            <!-- enableSubPackages:是否让schema作为包的后缀 -->
            <property name="enableSubPackages" value="false"/>
            <!-- 从数据库返回的值被清理前后的空格 -->
            <property name="trimStrings" value="true"/>
        </javaModelGenerator>
        <!-- targetProject:mapper映射文件生成的位置 -->
        <sqlMapGenerator targetPackage="com.tjetc.mapper"
                         targetProject=".\src\main\java">
            <!-- enableSubPackages:是否让schema作为包的后缀 -->
            <property name="enableSubPackages" value="false"/>
        </sqlMapGenerator>
        <!-- targetPackage:mapper接口生成的位置 -->
        <javaClientGenerator type="XMLMAPPER"
                             targetPackage="com.tjetc.mapper"
                             targetProject=".\src\main\java">
            <!-- enableSubPackages:是否让schema作为包的后缀 -->
            <property name="enableSubPackages" value="false"/>
        </javaClientGenerator>
        <!-- 指定数据库表 -->

        <!--<table schema="" tableName="t_user">
                        &lt;!&ndash; 取消表名_之前的前缀 &ndash;&gt;
                        <domainObjectRenamingRule searchString="^[^_]" replaceString="" />
                        <domainObjectRenamingRule searchString="^t_" replaceString="" />
                        &lt;!&ndash; 取消表字段_之前的前缀 &ndash;&gt;
                        <columnRenamingRule searchString="^[^_]+" replaceString=""/>
                </table>-->
        <table schema="" tableName="person">

        </table>



    </context>
</generatorConfiguration>

(3)

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.xml.ConfigurationParser;
import org.mybatis.generator.internal.DefaultShellCallback;

public class GeneratorSqlMap {

    public void generator() throws Exception {

        List<String> warnings = new ArrayList<String>();
        boolean overwrite = true;
        //指定 逆向工程配置文件
        File configFile = new File("generatorConfig.xml");
        ConfigurationParser cp = new ConfigurationParser(warnings);
        Configuration config = cp.parseConfiguration(configFile);
        DefaultShellCallback callback = new DefaultShellCallback(overwrite);
        MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config,
                callback, warnings);
        myBatisGenerator.generate(null);

    }

    public static void main(String[] args) throws Exception {
        try {
            GeneratorSqlMap generatorSqlmap = new GeneratorSqlMap();
            generatorSqlmap.generator();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

}

(4)点击右侧的Maven–mybatis-generator
然后点击mybatis-generator:generate

Spring&Mybatis整合

(1)在pom.xml文件中导入依赖

<dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.4</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>5.3.4</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>5.3.4</version>
        </dependency>

        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.6</version>
        </dependency>

        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>2.0.6</version>
        </dependency>


        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.23</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.13.2</version>
        </dependency>

        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.6</version>
        </dependency>

        
    </dependencies>


    <build>
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                </includes>
            </resource>
        </resources>
    </build>

(2)配置applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans
        xmlns="http://www.springframework.org/schema/beans"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:aop="http://www.springframework.org/schema/aop"
        xmlns:tx="http://www.springframework.org/schema/tx"
       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
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
">

    <!--配置扫描的基本包-->
    <context:component-scan base-package="com.tjetc"></context:component-scan>
    <!--加载属性文件-->
    <context:property-placeholder location="classpath*:db.properties"></context:property-placeholder>
    <!--配置数据源数据库连接池-->
    <bean id="DataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${jdbc.driver}"></property>
        <property name="url" value="${jdbc.url}"></property>
        <property name="username" value="${jdbc.user}"></property>
        <property name="password" value="${jdbc.password}"></property>
    </bean>
    <!--配置事务管理器-->
    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="DataSource"></property>
    </bean>
    <!--配置SqlSessionBean-->
    <bean id="SqlSession" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="DataSource"></property>
        <property name="configLocation" value="classpath:mybatis.xml"></property>
    </bean>
    <!--配置mybatis扫描mapper接口的基本包-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="beanName" value="sqlSession"></property>
        <property name="basePackage" value="com.tjetc.mapper"></property>
    </bean>
    <!--以下配置事务-->
    <aop:config>
        <!--切点-->
        <aop:pointcut id="txCut" expression="execution(* com.tjetc.service..*.*(..))"></aop:pointcut>
        <!--advisor 切点和事务增强器的桥梁-->
        <aop:advisor advice-ref="txAdvice" pointcut-ref="txCut"></aop:advisor>
    </aop:config>
    <!--配置事物的增强-->
    <tx:advice id="txAdvice" transaction-manager="txManager">
        <tx:attributes>
            <!--never从来没有事务 not_supported不支持事务 mandatory强制事务 required需要事务 -->
            <tx:method name="add*" propagation="REQUIRED"/>
            <tx:method name="update*" propagation="REQUIRED"/>
            <tx:method name="del*" propagation="REQUIRED"/>
            <tx:method name="*" read-only="true"/>
        </tx:attributes>
    </tx:advice>
</beans>

(3)配置mybatis.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"

        "http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>
    <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>
    <typeAliases>
        <package name="com.tjetc.domain"/>
    </typeAliases>

</configuration>

(4)把自动生成的com包复制过来
然后创建service接口和实现类

package com.tjetc.service;

import com.tjetc.domain.Person;

public interface PersonService {
    void add(Person person);
}

(5) 实现类

package com.tjetc.service.impl;

import com.tjetc.domain.Person;
import com.tjetc.mapper.PersonMapper;
import com.tjetc.service.PersonService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class PersonServiceImpl implements PersonService {
    @Autowired
    private PersonMapper personMapper;

    public void add(Person person) {
        personMapper.insert(person);
    }
}

(6)测试类

package com.tjetc.test;

import com.tjetc.domain.Person;
import com.tjetc.service.PersonService;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test1 {
    @Test
    public void testAdd(){
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        PersonService personServiceImpl = (PersonService) context.getBean("personServiceImpl");
        Person person = new Person();
        person.setName("zs");
        person.setAge(20);
        personServiceImpl.add(person);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

香鱼嫩虾

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值