spring Bean的作用域
scope可以取值:
*singleton:每次调用getBean的时候返回相同的实例
*prototype:每次调用getBean的时候返回不同的实例
spring 的自动装配
根据名字自动装配,一般适合快速开发
spring JDK动态代理
Aspect切面类:
public class SecurityHandler implements InvocationHandler {
private Object targetObject;
public Object newProxy(Object targetObject){
this.targetObject = targetObject;
return Proxy.newProxyInstance(targetobject.getClass().getClassLoader(),
targetobject.getClass.getInterfaces(),
this);
}
public Object invoke(Object proxy, Method method ,Object[] args)
throws Throwable{
checkSecurity();
Object ret = null;
try{
ret = method.invoke(this.targetObject, args);
}catch(Exception e){
e.printStackTrace();
throw new java.lang.RuntimeException(e);
}
return ret;
}
<!--横切性关注点的实现(advice)-->
private void checkSecurity(){
System.out.println("------checkSecurity()--------");
}
}
Aop是发现这些横切性问题,然后把它模块化,模块化的类通常称切面(aspect),切面类中有adivce,就是检查
安全性的实现类(checkSecurity()),把adivce应用到目标对象的过程叫织入(weave)。
横切性关注点(cross cutting concern),
方法称为连接点(join)
spring Aop的使用执行(Annotation)
1.依赖库
*.SPRING_HOME/dist/spring.jar
*.SPRING_HOME/lib/jarkarta-commons/commons-logging.jar
*.SPRING_HOME/lib/log4j/log4j-1.2.14.jar
*.SPRING_HOME/lib/aspectj/*.jar
2.采用Aspect定义切面
3.在Aspect定义Pointcut和Adivce
4.启用Aspect对Annotation的支持并且将Aspect类和目标对象配置到Ioc容器中
注意:在这种方法定义中,切入点的方法不被执行的,它存在的目的仅仅是为了重用切入点即Adivce
中通过方法引用这个切入点
@Aspect
public class SecurityHander {
@Pointcut("execution(*add*(..))")//描述哪些对象的那些方法
private void allAddMethod(){};
@Before("assAllMethod()") //定义Adivce,标识在哪个切入点何处织入此方法
private void checkSecurity(){
System.out.println("---checkSecutiry()---");
}
}
--------------------------------------------------------------------------------------
spring 对Aop的执行(采用配置文件的方式)
配置如下:
<aop:config>
<aop:aspect id="security" ref="securityHandler">
<aop:pointcut id="allAddMethod" expression="execution(* com.bjsxt.spring.UserMangerImpl.add*(..))"/>
<aop:before method=“checkSecurity” pointcut-ref="allAddMethod"/>
</aop:aspect>
</aop:config>
---------------------------------------------------------------------------------------------------------------
spring对AOP的支持
Aspect默认情况下不用实现接口,但对于目标对象(UserManagerImpl.java),在默认情况下必须实现接口
如果没有实现接口必须引入CGLIB库;如果目标对象实现了接口,默认对象会采用JDK的动态代理实现AOP,也可以
强制使用CGLIB实现AOP,如果目标对象没有实现接口,必须采用CGLIB库,spring会在JDK动态代理和CGLIB自动转换
我们可以通过Adivce中添加一个JoinPoint参数,这个值会由spring自动传入,从JoinPoint中可以取得参数值
、方法名等。
private void checkSecurity(JoinPoint joinPoint){
Object[] args = JoinPoint.getArgs();
for (int i=0; i<args.length; i++){
System.out.println(args[i]);
}
System.out.println(joinPoint.getSignature().getName());
}
如何实强制使用CGLIB实现AOP?
*添加DGLIB库,SPRING_HOME/cdlib/*.jar
*在applicationContext.xml中加入<aop:aspectj-autoproxy proxy-target-class="true"/>
JDK动态代理和CGLIB字节码生成的区别?
*JDK动态代理只能对实现了接口的类生成代理,而不能针对类
*CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法
因为是继承,所以该类或方法最好不要声明成final