目录
一、反射
什么是反射?
反射是运行状态中,任意一个类都能获取这个类的所有属性和方法,任意一个对象都能调用它的一个方法和属性,动态获取类信息和动态获取对象内容。
获取类信息的三种方式
1、对象.getClass() 2、类.forName("java.lang.String") 3、类名.class
//方法一:
Class<?> clas = Class.forName("java.lang.Object");
//方法二:通过类的名字打打点class,如
Class<?> clas1 = Object.class;
//方法三:通过该类的对象去调用getClass()方法,如
Class<?> clas2 = new Object().getClass();
System.out.println(clas.toString());
//它们的结果都是: class java.lang.Object
反射进行赋值
方法一(直接暴力赋值)
根据方法名字来获得属性对象,破坏掉私有属性,然后赋值
public class A {
private String a;
}
public class Demo0813 {
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
A al = new A();
Class c1 = al.getClass();
Field x = c1.getDeclaredField("a");
x.setAccessible(true);
x.set(al,"张三");
System.out.println(x.get(al));
}
}
输出为
张三
方法二(Method反射调用自身)
指定setXxx方法,通过Method反射调用自身;关键方法invoke(Obkect obj, Object…args)
public class Demo0813 {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
Class<?> aClass = Class.forName("entity.A");
Object ol = aClass.newInstance();
Method setName = aClass.getDeclaredMethod("setName",String.class);
setName.setAccessible(true);
setName.invoke(ol,"李四");
Method getName = aClass.getDeclaredMethod("getName");
getName.setAccessible(true);
Object invoke = getName.invoke(ol);
System.out.println(invoke);
}
}
输出为
李四
二、代理
什么是代理
代理是一种设计模式;给目标对象提供一个代理对象,并且由代理对象控制对目标对象的引用。
目的是:
通过代理对象的方式间接的访问目标对象,防止直接访问目标对象给系统带来不必要的复杂性
通过代理业务对原有业务进行增强
代理又分为静态代理和动态代理
静态代理
静态代理是由程序员创建或工具生成代理类的源码,再编译代理类,即代理类和委托类的关系再程序运行前就已经存在。
静态代理的好处
可以隐藏委托类的具体实现;
可以在不改变委托类的情况下增加额外的操作
接口实现
public interface Singer {
void singMethod();
int sing(Integer i);
}
实现类
public class Cat implements Singer {
@Override
public void singMethod() {
System.out.println("cat 唱歌");
}
@Override
public int sing(Integer i) {
System.out.println("cat 跳舞");
return i;
}
}
代理类
public class CatProxy implements Singer {
Cat cat = new Cat();
@Override
public void singMethod() {
System.out.println("方法执行前");
cat.singMethod();
System.out.println("方法执行后");
}
@Override
public int sing(Integer i) {
System.out.println("方法执行前");
int haha = cat.sing(i);
System.out.println("方法执行后");
return haha;
}
}
输出为
方法执行前
cat 唱歌
方法执行后
-----------------------------
方法执行前
cat 跳舞
方法执行后
666
jdk动态代理
JDK动态代理基本接口实现,通过接口指向实现类实例的多态方式,可以有效地将具体实现与调用解耦,便于后期的修改和维护。
public class CatUser {
public static void main(String[] args) {
Cat cat = new Cat();
Money money = new Money(cat);
Object a = Proxy.newProxyInstance(Cat.class.getClassLoader(),Cat.class.getInterfaces(),money);
if (a instanceof Singer){
Singer singer = (Singer) a;
singer.singMethod();
System.out.println(singer.sing(3));
singer.toString();
}
}
static class Money implements InvocationHandler{
private Singer singer;
public Money(Singer singer){
this.singer = singer;
}
@Override
public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
System.out.println("快乐如此简单");
Object invoke = method.invoke(singer,objects);
return invoke;
}
}
}
输出为
快乐如此简单
cat 唱歌
快乐如此简单
cat 跳舞
3
快乐如此简单
Cglib实现代理
public class TargetProxy {
static <T> Object getProxy(T t) {
Enhancer en = new Enhancer(); //帮我们生成代理对象
en.setSuperclass(t.getClass());//设置要代理的目标类
en.setCallback(new MethodInterceptor() {//代理要做什么
@Override
public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
System.out.println("执行方法前。。。");
//调用原有方法
Object invoke = methodProxy.invokeSuper(object, args);
// Object invoke = method.invoke(t, args);// 作用等同与上面。
System.out.println("执行方法后。。。");
return invoke;
}
});
return en.create();
}
}
输出为
执行方法前。。。
method1 running ...
执行方法后。。。
jdk实现InvocationHandler类 重写invoke实现切面,cglib实现MethodInterceptor类 重写intercept实现切面
jdk代理是生成代理对象 会调用invoke方法,cglib利用ASM技术 直接编译到class内
jdk代理是作用在interface上, cglib代理可以是任意类 final除外
AOP
代理目标接口
public interface TargetInteface {
void method1();
void method2();
int method3(Integer i);
}
实现类
public class Target implements TargetInteface{
/*
* 需要增强的方法,连接点JoinPoint
**/
public void method1() {
System.out.println("method1 running ...");
}
public void method2() {
System.out.println("method2 running ...");
}
public int method3(Integer i) {
System.out.println("method3 running ...");
return i;
}
}
增强类
public class TargetAdvice implements MethodInterceptor, MethodBeforeAdvice, AfterReturningAdvice {
/*
* 通知/增强
**/
@Override
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
System.out.println("前置环绕通知");
Object proceed = methodInvocation.proceed();
System.out.println("后置环绕通知");
return proceed;
}
@Override
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
System.out.println("后置返回通知");
}
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println("前置通知");
}
}
main方法
public class AopTest {
public static void main(String[] args) {
ApplicationContext appCtx = new ClassPathXmlApplicationContext("spring-aop.xml");
Target targetProxy = (Target) appCtx.getBean("targetProxy");
targetProxy.method1();
}
}
spring-aop.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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">
<bean id="target" class="com.heaboy.aopdemo.aop.Target"/>
<bean id="targetAdvice" class="com.heaboy.aopdemo.aop.TargetAdvice"/>
<bean id="targetProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target" ref="target"/> <!--被代理的类-->
<property name="interceptorNames" value="targetAdvice"/> <!--如果用多种增强方式,value的值使用逗号(,)分割-->
<property name="proxyTargetClass" value="true"/>
<property name="interfaces" value="com.heaboy.aopdemo.aop.TargetInteface"/> <!--target实现的接口-->
</bean>
</beans>