Spring02

158 阅读2分钟

SpringBean管理注解

@Component

三个衍生组件

  • @Controller、@Service、@Repository

属性注入

  • @Value 注入普通属性
  • @Autowired 自动装配:按照类型装配、按照名称注入。
    • @Qualifier 强制使用名称注入
  • @Resource 相当于@Autowired 和@Qualifier 一起使用

生命周期注解

@PostConstruct 相当于init-method

@PreDestory 相当于destory-method

基于XML vs 注解配置

12.PNG

Spring AOP编程

代理机制
  • JDK动态代理
public interface UserDao {
   String getName(int id) ;
}
public class UserDaoImpl implements UserDao {
    @Override
     public String getName(int id) {
        return   "bach";
    }
}
public class MyJDKProxy implements InvocationHandler {
    private UserDao userDao;
    public MyJDKProxy(UserDao userDao) {
        this.userDao = userDao;
    }
    public UserDao creatProxy(){
      //  System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles","true");
        UserDao o = (UserDao) Proxy.newProxyInstance(userDao.getClass().getClassLoader(),
                userDao.getClass().getInterfaces(), this);
        return o;
    }

    @Override
    public Object invoke(Object proxy,Method method, Object[] args) throws Throwable {
        if (method.getName().equals("getName")){
            System.out.println("print by InvocationHandler");
        }
        return method.invoke(userDao,args);
    }

    public static void main(String[] args) {
        MyJDKProxy proxy = new MyJDKProxy(new UserDaoImpl());
        UserDao userDao = proxy.creatProxy();
        userDao.getName(2);
    }
}
  • CGlib动态代理(使用ASM字节码操纵框架实现)
public class MyCglibProxy implements MethodInterceptor {

    public UserDao creatProxy(){
        Enhancer enhancer = new Enhancer();
        //设置base类
        enhancer.setSuperclass(UserDaoImpl.class);
        //设置回调。
        enhancer.setCallback(this);
        //产生继承类
        return (UserDao) enhancer.create();
    }

    @Override
    public Object intercept(Object proxy, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        if (method.getName().equals("getName")){
            Object o = methodProxy.invokeSuper(proxy, objects);
            System.out.println("日志记录");
            return o;
        }
        return methodProxy.invokeSuper(proxy,objects);
    }

    public static void main(String[] args) {
        //产生方法拦截器
        MyCglibProxy intercept = new MyCglibProxy();
        //产生代理
        UserDao userDao = intercept.creatProxy();
        userDao.getName(2);
    }
}

  • JDK动态代理和Cglib代理之间的对比
代理类 拦截器 目标类
JDK 实现目标类实现的接口 InvocationHandler 聚合/组合到拦截器里面
Cglib 继承自目标类 MethedIntecepter 代理类的父类
SpringAOP 和 AspectJ的区别和联系

首先解释动态代理和静态代理,静态代理指的是在编译时或者类加载就已经产生了代理对象的字节码,如AspectJ。而动态代理是在运行期产生代理对象,Spring采用的是这种方式。Spring借鉴了AspectJ对于AOP的注解,但是没有使用AspectJ的编译器(需要特殊编译器)。静态代理在速度上更有优势。

通知

拦截到切入点之后要做的事情,包括何时(拦截点之前、之后)、如何做。

前置、后置、环绕、异常抛出、最终通知

切点表达式语言

execution(【访问修饰符】 返回值 包名.类名.方法(方法参数))

* cn.itcast.spring.dao.*.*(..)

配置
<aop:config>
    <aop:pointcut expression="execution(..)" id="切点id">
    	<aop:aspect ref="切面类id">
            <aop:before method="切面类方法" pointcur-ref="切点id"
        </aop:aspect>
    </aop:pointcut>
</aop:config>