一个例子:
package com.zg.spring.proxy;
/**
* @Auther: zhaoss
* @Date: 2022/8/2 - 08 - 02 - 23:16
* @Description: com.zg.spring.proxy
* @version: 1.0
*/
public interface Calculator {
int add(int i, int j);
int sub(int i, int j);
int mul(int i, int j);
int div(int i, int j);
}
package com.zg.spring.proxy;
/**
* @Auther: zhaoss
* @Date: 2022/8/2 - 08 - 02 - 23:17
* @Description: com.zg.spring.proxy
* @version: 1.0
*/
public class CalculatorImpl implements Calculator {
@Override
public int add(int i, int j) {
System.out.println("日志,方法:add,参数:"+i+","+j);
int result = i+j;
System.out.println("计算结果为"+result);
return result;
}
@Override
public int sub(int i, int j) {
System.out.println("日志,方法:sub,参数:"+i+","+j);
int result = i-j;
System.out.println("计算结果为"+result);
return result;
}
@Override
public int mul(int i, int j) {
System.out.println("日志,方法:mul,参数:"+i+","+j);
int result = i*j;
System.out.println("计算结果为"+result);
return result;
}
@Override
public int div(int i, int j) {
System.out.println("日志,方法:div,参数:"+i+","+j);
int result = i/j;
System.out.println("计算结果为"+result);
return result;
}
}
package com.zg.spring.proxy;
import java.lang.reflect.Array;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
/**
* @Auther: zhaoss
* @Date: 2022/8/2 - 08 - 02 - 23:19
* @Description: com.zg.spring.proxy
* @version: 1.0
*/
public class ProxyFactory {
public ProxyFactory(Object target) {
this.target = target;
}
private Object target;
public Object getProxy(){
// lassLoader loader, 指定加载动态生成的代理类的类加载器
// Class<?>[] interfaces, 获取目标对象实现的所有接口的class对象数组
// InvocationHandler h)
ClassLoader classLoader = this.getClass().getClassLoader();
Class<?>[] interfaces = target.getClass().getInterfaces();
InvocationHandler h = new InvocationHandler() {
@Override
//proxy 代理对象,method要执行的方法,args 要执行的方法的参数列表
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("日志,方法: " +method.getName()+", 参数:"+ Arrays.toString(args));
Object res = method.invoke(target, args);
System.out.println("日志,方法: " +method.getName()+", 结果:"+ res);
return res;
}
};
return Proxy.newProxyInstance(classLoader,interfaces,h);
}
}
package com.zg.test;
import com.zg.spring.proxy.Calculator;
import com.zg.spring.proxy.CalculatorImpl;
import com.zg.spring.proxy.ProxyFactory;
import org.junit.Test;
/**
* @Auther: zhaoss
* @Date: 2022/8/2 - 08 - 02 - 23:51
* @Description: com.zg.test
* @version: 1.0
*/
public class ProxyTest {
@Test
public void testProxy(){
ProxyFactory proxyFactory = new ProxyFactory(new CalculatorImpl());
Calculator proxy = (Calculator)proxyFactory.getProxy();
proxy.add(1,2);
proxy.mul(3,6);
}
}
<?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.zg.sbootT1</groupId>
<artifactId>sbootT1</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.22</version>
</dependency>
<!--junit测试-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!--MyBatis驱动-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.6</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.14</version>
</dependency>
<!--Spring连接Mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.26</version>
</dependency>
<!--数据源-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.31</version>
</dependency>
</dependencies>
</project>
使用基于注解的AOP:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<!--
AOP的注意事项:
切面类和目标类都需要交给IOC容器管理
切面类必须通过@Aspect注解标识为一个切面
在Spring的配置文件中设置<aop:aspectj-autoproxy />开启基于注解的AOP
-->
<!--扫描-->
<context:component-scan base-package="com.zg.spring.aop.annotation"></context:component-scan>
<!--开启基于注解的AOP-->
<aop:aspectj-autoproxy />
</beans>
package com.zg.spring.aop.annotation;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import java.util.Arrays;
@Component
@Aspect //切面
public class LoggerAspect {
// @Before("execution(public int com.zg.spring.aop.annotation.CalculatorImpl.add(int,int))")
// //@Before("execution(public int com.zg.spring.aop.annotation.CalculatorImpl.*(..))")
// public void beforeAdviceMethod(){
// System.out.println("LoggerAspect,前置通知");
// }
@Pointcut("execution(* com.zg.spring.aop.annotation.CalculatorImpl.*(..))")
public void pointCut(){}
public void beforeAdviceMethod(JoinPoint joinPoint){
//获取连接点所对应方法的签名信息
Signature signature = joinPoint.getSignature();
//获取连接点所对应方法的参数
Object[] args = joinPoint.getArgs();
System.out.println("LoggerAspect,方法:"+signature.getName()+",参数:"+ Arrays.toString(args));
}
@After("pointCut()")
public void afterAdviceMethod(JoinPoint joinPoint){
//获取连接点所对应方法的签名信息
Signature signature = joinPoint.getSignature();
System.out.println("LoggerAspect,方法:"+signature.getName()+",执行完毕");
}
/**
* 在返回通知中若要获取目标对象方法的返回值
* 只需要通过@AfterReturning注解的returning属性
* 就可以将通知方法的某个参数指定为接收目标对象方法的返回值的参数
*/
@AfterReturning(value = "pointCut()", returning = "result")
public void afterReturningAdviceMethod(JoinPoint joinPoint, Object result){
//获取连接点所对应方法的签名信息
Signature signature = joinPoint.getSignature();
System.out.println("LoggerAspect,方法:"+signature.getName()+",结果:"+result);
}
/**
* 在异常通知中若要获取目标对象方法的异常
* 只需要通过AfterThrowing注解的throwing属性
* 就可以将通知方法的某个参数指定为接收目标对象方法出现的异常的参数
*/
@AfterThrowing(value = "pointCut()", throwing = "ex")
public void afterThrowingAdviceMethod(JoinPoint joinPoint, Throwable ex){
//获取连接点所对应方法的签名信息
Signature signature = joinPoint.getSignature();
System.out.println("LoggerAspect,方法:"+signature.getName()+",异常:"+ex);
}
@Around("pointCut()")
//环绕通知的方法的返回值一定要和目标对象方法的返回值一致
public Object aroundAdviceMethod(ProceedingJoinPoint joinPoint){
Object result = null;
try {
System.out.println("环绕通知-->前置通知");
//表示目标对象方法的执行
result = joinPoint.proceed();
System.out.println("环绕通知-->返回通知");
} catch (Throwable throwable) {
throwable.printStackTrace();
System.out.println("环绕通知-->异常通知");
} finally {
System.out.println("环绕通知-->后置通知");
}
return result;
}
}
package com.zg.spring.aop.annotation;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Component
@Aspect
@Order(1)
public class ValidateAspect {
//@Before("execution(* com.atguigu.spring.aop.annotation.CalculatorImpl.*(..))")
@Before("com.zg.spring.aop.annotation.LoggerAspect.pointCut()")
public void beforeMethod(){
System.out.println("ValidateAspect-->前置通知");
}
}
package com.zg.spring.test;
import com.zg.spring.aop.annotation.Calculator;
import com.zg.spring.aop.annotation.CalculatorImpl;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class AOPTest {
@Test
public void testAOPByAnnotation(){
ClassPathXmlApplicationContext ioc = new ClassPathXmlApplicationContext("aop-annotation.xml");
//使用了AOP 就不能直接访问,必须通过代理对象访问。
// CalculatorImpl calculator = ioc.getBean(CalculatorImpl.class);
// calculator.add(3,4);
Calculator calculator = ioc.getBean(Calculator.class);
calculator.add(3,4);
}
}
ssm练习:
properties配置:
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/OneToMany?useUnicode=true&characterEncoding=utf8&autoReconnect=true&serverTimezone=UTC
jdbc.username=root
jdbc.password=123456
mybatis-config.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>
<!--properties,settings,typeAliases, typeHandles, objectFactory,plugins,environment-->
<!--引入properties 以后就可以用${key}方式访问value-->
<properties resource="jdbc.properties"/>
<typeAliases>
<package name="com.zg.mybatis.project"/>
</typeAliases>
<plugins>
<!--配置分页插件-->
<plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
</plugins>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<!--<mapper resource="mappers/AticleMapper.xml"/>-->
<!--mapper和mapper.xml放在同一目录下,映射接口DAO和xml不用一个一个映射了-->
<package name="com.zg.mybatis.mapper"/>
</mappers>
</configuration>
package com.zg.mybatis.utils;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
/**
* @Auther: zhaoss
* @Date: 2022/7/26 - 07 - 26 - 0:47
* @Description: com.zg.mybatis.utils
* @version: 1.0
*/
public class SqlSessionUtil {
public static SqlSession getSqlSession(){
SqlSession sqlSession =null;
try {
//获取核心配置文件输入流
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
//获取SqlSessionFactory对象
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
SqlSessionFactory build = sqlSessionFactoryBuilder.build(is);
//获取sql会话对象SqlSession
sqlSession = build.openSession(true);
} catch (IOException e) {
e.printStackTrace();
}
return sqlSession;
}
}
package com.zg.mybatis.mapper;
import com.zg.mybatis.project.Aticle;
import org.apache.ibatis.annotations.MapKey;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
public interface AticleMapper {
//int insertAticle();
Aticle getAticleById();
Aticle getAticleByTitle(String Title);
Aticle getAticleByTitleAndMsg(String Title, String Msg);
Aticle getAticleByTitleAndMsgByMap(Map<String,Object> map);
List<Aticle> getAllAticle();
void insertAticle(Aticle aticle);
//可以在mapper接口上使用@Param 注解,这样@Param("Title") 列名被标注为map的键
void insertAticleByParam(@Param("Title") String t, @Param("Message") String msg);
//通过param 定义键值对 @Param("Id") 为键,表名,String id 为传入值
Aticle getAticleByIdParam(@Param("Id") String id);
int getCount();
//根据Id查询所有值,并返回键值对
List<Map<String, Object>> getAticleByIdToMap();
//使用Map注解:"id"区分大小写
@MapKey("id")
Map<String, Object> getAticleByIdToMap2();
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://10.20.91.130/dtd/mybatis-3-mapper.dtd" >
<!--关联DAO-->
<mapper namespace="com.zg.mybatis.mapper.AticleMapper">
<!--mapper接口的全类名要和映射文件的namespace保持一致-->
<!--mapper接口中的方法的方法名要和映射文件sql中的Id保持一致-->
<!--int insertAticle();-->
<!--<insert id="insertAticle">-->
<!--insert into Aticle values(null, "admin","123456")-->
<!--</insert>-->
<!--Aticle getAticleById()-->
<!--result type 设置结果类型 -->
<!--result map 自定义映射,处理一对一或者多对多-->
<select id="getAticleById" resultType="com.zg.mybatis.project.Aticle">
select * from Aticle where id=1
</select>
<!--在mybatisconfig里配置完就不用配置resultType了-->
<!--<typeAliases>-->
<!--<package name="com.zg.mybatis.project"/>-->
<!--</typeAliases>-->
<!--List<Aticle> getAllAticle()-->
<select id="getAllAticle" resultType="Aticle">
select * from Aticle
</select>
<!--getAticleByTitle(String Title);-->
<select id="getAticleByTitle" resultType="Aticle">
<!--select * from Aticle where Title=#{xxxx}-->
<!--#相当于占位符,不用手动加单引号。 $是sql拼接-->
select * from Aticle where Title = '${xxxx}'
</select>
<!--getAticleByTitleAndMsg(String Title, String Msg)-->
<select id="getAticleByTitleAndMsg" resultType="Aticle">
<!--select * from Aticle where Title = #{param1} and Message = #{param2}-->
select * from Aticle where Title = #{arg0} and Message = #{arg1}
</select>
<!--Title 为map中的键,#{Title} 寻找到key所对应的值-->
<!--Aticle getAticleByTitleAndMsgByMap(Map<String,Object> map);-->
<select id="getAticleByTitleAndMsgByMap" resultType="Aticle">
select * from Aticle where Title = #{Title} and Message = #{Message}
</select>
<!--void insertAticle(Aticle aticle);-->
<insert id="insertAticle" >
insert into Aticle values(null, #{Title}, #{Message})
</insert>
<!--void insertAticleByParam(Aticle aticle);-->
<insert id="insertAticleByParam">
insert into Aticle values(null, #{Title}, #{Message})
</insert>
<!--Aticle getAticleByIdParam(@Param("Id") String id);-->
<select id="getAticleByIdParam" resultType="Aticle">
select * from Aticle where Id = #{Id}
</select>
<!--int getCount();-->
<select id="getCount" resultType="int">
select count(*) from Aticle
</select>
<!--Map<String, Object> getAticleByIdToMap();-->
<select id="getAticleByIdToMap" resultType="map">
select * from Aticle
</select>
<!--Map<String, Object> getAticleByIdToMap2();-->
<select id="getAticleByIdToMap2" resultType="map">
select * from Aticle
</select>
</mapper>
package com.zg.mybatis.project;
public class Aticle {
public Aticle() {
}
public Aticle(Integer id, String title, String message) {
this.id = id;
Title = title;
Message = message;
}
private Integer id;
private String Title;
private String Message;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getTitle() {
return Title;
}
public void setTitle(String title) {
Title = title;
}
public String getMessage() {
return Message;
}
public void setMessage(String message) {
Message = message;
}
@Override
public String toString() {
return "Aticle{" +
"id=" + id +
", Title='" + Title + '\'' +
", Message='" + Message + '\'' +
'}';
}
}