一:使用配置文件xml将域属性进行自动注入
<bean id="car" class="cn.entity.Car" > <property name="brand" value="奥迪"></property> <property name="color" value="黑色"></property> </bean> <bean id="stu" class="cn.entity.Student" autowire="byName"> <constructor-arg index="0" value="18"></constructor-arg> <constructor-arg index="1" value="李胖子"></constructor-arg> <!-- <constructor-arg index="2" ref="car"></constructor-arg> --> </bean>
package cn.entity; import javax.annotation.Resource; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @Component(value="stu") public class Student { @Value("18") private int age; @Value("张三") private String name; @Resource private Car car; public Car getCar() { return car; } public void setCar(Car car) { this.car = car; } public int getAge() { return age; } public String getName() { return name; } public void setAge(int age) { this.age = age; } public void setName(String name) { this.name = name; } public Student() { System.out.println("Student.Student()"); } public Student(int age, String name, Car car) { super(); this.age = age; this.name = name; this.car = car; } @Override public String toString() { return "Student [age=" + age + ", name=" + name + ", car=" + car + "]"; } }
byName方式域属性自动注入,要求自动注入的Bean的id名称要与被注入的属性名相同!
域属性自动注入 byType方式
byType方式域属性自动注入,要求容器中与被注入属性类型具有is-a关系的bean,只能有一个
二:实现静态代理
如何实现静态代理:
代码如下:
package entity; public interface Proxy { public String execute(); } package entity; public class realProxy implements Proxy{ @Override public String execute() { System.out.println("Real"); return "呵呵"; } } package entity; public class ProxyAct implements Proxy { realProxy real=new realProxy(); @Override public String execute() { System.out.println("before"); real.execute(); System.out.println("after"); return "ss"; } } package entity; public class Test { public static void main(String[] args) { ProxyAct act=new ProxyAct(); act.execute(); } }
其本质也就是说使用代理类同样实现一个接口,并重写其中的抽象方法,在重写方法中调用非代理对象的重写方法,并且在其中加入增强代码,以实现增强业务逻辑的功能!
三:jdk的动态代理
使用jdk的动态代理,例:
package dymicProxy; public interface Model { public void add(); public void edit(); } package dymicProxy; public class ModeImpl implements Model { @Override public void add() { System.out.println("add ok!"); } @Override public void edit() { System.out.println("edit ok!"); } } package dymicProxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class dymicProxyinvoke { public static void main(String[] args) { final Model mo=new ModeImpl(); Model object =(Model) Proxy.newProxyInstance(mo.getClass().getClassLoader(), mo.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("tran"); method.invoke(mo, args); System.out.println("close"); return null; } }); object.add(); object.edit(); } }
在代理类中的newProxyInstance()方法传入三个参数:A:实现类的类加载器,B:实现类实现的接口,C:以及InvocationHandler接口的重写方法
method 指需要重写的方法,args指需要传递的方法参数,最后使用代理对象调用实现类的方法,可以发现为实现类的方法实现了前置和后置增强。需要注意的是:method.invoke();方法只能调用使用final修饰的变量,
因为虽然匿名内部类在方法的内部,但实际编译的时
候,内部类编译成Outer.Inner,这说明内部类所处的位置和外部类中的方法处在同一个等级上,外部类中的方法中的变量或参数只是方法的局部变量,这些变量或参数的作用域只在这个方法内部有效。因为编译的时候内部类和方法在同一级别上,所以方法中的变量或参数只有为final,内部类才可以引用!
jdk的动态代理
本质:在内存中构建出接口的实现类
特点:被代理对象,必须有接口
四:cglib动态代理
本质:在内存中生成被代理对象的【子类】
特点:可以在没有接口的情况下代理
对于不使用接口的业务类,无法使用JDK动态代理,cglib采用非常底层的字节码技术,可以为一个类创建
子类,解决无接口代理问题
package cglib; public class Service { public void request() { System.out.println("主业务"); } } package cglib; import java.lang.reflect.Method; import org.springframework.cglib.proxy.Enhancer; import org.springframework.cglib.proxy.MethodInterceptor; import org.springframework.cglib.proxy.MethodProxy; public class cglibService { final Service ser=new Service(); Enhancer enhancer=new Enhancer(); public static void main(String[] args) { final Service ser=new Service(); Enhancer enhancer=new Enhancer(); enhancer.setSuperclass(ser.getClass()); enhancer.setCallback(new MethodInterceptor() { @Override public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable { System.out.println("before"); arg1.invoke(ser, arg2); System.out.println("after"); return null; } }); Service proxy=(Service)enhancer.create(); proxy.request(); } }