Spring源码解读以及Spring整体结构浅析

扫码关注公众号:Java 技术驿站

发送:vip
将链接复制到本浏览器,永久解锁本站全部文章

【公众号:Java 技术驿站】 【加作者微信交流技术,拉技术群】
  • BeanFactory结构图
  • Spring容器启动过程
  • Bean实例化过程

2019102020030\_1.png

1、bean实现Aware接口的意义(图中检查Aware相关接口并设置相关依赖)

    package com.anotation.bean;

    import org.springframework.beans.BeansException;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.ApplicationContextAware;
    import org.springframework.stereotype.Component;

    import javax.annotation.PostConstruct;
    import javax.annotation.PreDestroy;

    @Component
    public class Dog implements ApplicationContextAware {

        private String name;

        //10公;20母
        private Integer sex;

        private ApplicationContext applicationContext;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public Integer getSex() {
            return sex;
        }

        public void setSex(Integer sex) {
            this.sex = sex;
        }

        public Dog(){
            System.out.println("dog constructor...");
        }

        //对象创建并赋值之后调用
        @PostConstruct
        public void init(){
            System.out.println("Dog....@PostConstruct...");
        }

        //容器移除对象之前调用
        @PreDestroy
        public void detory(){
            System.out.println("Dog....@PreDestroy...");
        }

        //实现ApplicationContextAware接口,并重写他的setApplicationContext()方法,可以让当前对象拥有容器的ApplicationContext引用
        @Override
        public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
            this.applicationContext = applicationContext;
        }

        @Override
        public String toString() {
            return "Dog{" + "name='" + name + '\'' + ", sex=" + sex + '}';
        }
    }

2、实现BeanPostProcessor的作用:他的两个方法都传入了对象实例的引用,这为我们扩展容器的对象实例化过程中的行为提供了极大的便利,我们几乎可以对传入的对象实例做任何操作

    package com.anotation.bean;

    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.config.BeanPostProcessor;
    import org.springframework.stereotype.Component;

    /**
     *
     * 创建一个BeanPost类,实现BeanPostProcessor接口。
     * 在其postProcessAfterInitialization()方法中修改通过参数传入的受管Bean,然后返回。
     * 由于它处理容器中的每一个Bean,因此在修改前,应判断Bean是否为我们要处理的Bean。
     * 可以通过传入Bean的类型判定,也可以通过传入Bean的名字判定
     *
     * @author zhengchao
     */
    @Component
    public class MyBeanPostProcessor implements BeanPostProcessor {

        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {

            System.out.println("postProcessBeforeInitialization..." + beanName + "=>" + bean);
            System.out.println("BeanPostProcessor.postProcessAfterInitialization 正在预处理!");
            //过滤特定类型的bean来修改bean的属性或其为其进行增强(AOP就是基于此原理)
            if ((bean instanceof Dog)){
                Dog dog = (Dog) bean;
                dog.setName("范冰冰");
                dog.setSex(20);
                return bean;
            }
            return bean;
        }

        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            System.out.println("postProcessAfterInitialization..." + beanName + "=>" + bean);
            return bean;
        }
    }

3、spring Aop手写实现

    public interface ITask {
        void execute();
    }

    public class TaskImpl implements ITask{
        @Override
        public void execute() {
            Date date = new Date();
            System.out.println("信息:["+date+"] 调用了execute()方法。");
        }
    }

    import org.springframework.aop.AfterReturningAdvice;
    import org.springframework.aop.MethodBeforeAdvice;
    import java.lang.reflect.Method;
    import java.util.Date;
    /**
     * 基于jdk的动态代理实现自己的aop: pointcut&&advice (还有一种cglib)
     */
    public class MethodBeforeAdviceImpl implements MethodBeforeAdvice, AfterReturningAdvice {

        //拦截方法之前执行
        @Override
        public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable {
            Date date = new Date();
            System.out.println("信息:["+date+"] 调用了before()方法。");
        }

        //拦截方法返回结果之后执行
        @Override
        public void afterReturning(Object returnValue, Method method, Object[] args, Object target)
                throws Throwable {
            Date date = new Date();
            System.out.println("信息:["+date+"] 调用了afterReturning()方法。");
        }
    }

    public class MainTest {

        public static void main(String[] args) {
            TaskImpl task = new TaskImpl();

            NameMatchMethodPointcut pc=new NameMatchMethodPointcut();
            pc.addMethodName("execute");

            Advice advice=new MethodBeforeAdviceImpl();
            Advisor advisor=new DefaultPointcutAdvisor(pc,advice);

            //创建BeanOne代理
            ProxyFactory pf1=new ProxyFactory();
            pf1.addAdvisor(advisor);
            pf1.setTarget(task);
            ITask proxyObject = (ITask)pf1.getProxy();
            proxyObject.execute();
        }
    }

    返回:
    信息:[Mon Oct 22 21:28:12 CST 2018] 调用了before()方法。
    信息:[Mon Oct 22 21:28:12 CST 2018] 调用了execute()方法。
    信息:[Mon Oct 22 21:28:12 CST 2018] 调用了afterReturning()方法。

to be continue

赞(0) 打赏
版权归原创作者所有,任何形式的转载请联系博主:daming_90:Java 技术驿站 » Spring源码解读以及Spring整体结构浅析

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏