每天学点Java之Spring注解与AOP

Spring使用注解配置bean

1.使用注解配置bean步骤
    (1.在配置文件中添加context命名空间 
    xmlns:context="http://www.springframework.org/schema/context"
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-4.3.xsd"
    (2.添加aop jar包
    (3.扫描注解
    配置文件中添加:
<context:component-scan base-package="包名"></context:component-scan> 
    会扫描指定的包名下的所有子孙包
2.注解介绍
  (1.只能加在类上 如果没有指定bean名字 默认是以小写开头的类名
      为其指定名字: Component("name")
    Component 
    Service       对应Service业务逻辑层
    Controller    对应Action Servlet
    Repository    对应数据库相关(Dao)
    下面三个是Component的衍生标签 作用是一样的 但是这三个标签更加语义化 
    更符合 JavaEE分层思想
   (2.使用以上注解配置bean时 可以使用@Value("值")配置bean属性的值
       @Value() 可以写在属性上 也可以写在set方法上
       但是写在属性上会破坏对象的封装性 建议写在set方法上
   (3.Scope注解 用来控制bean的作用域 例:@Scope(scopeName="singleton")
       Scope注解也是写在类上 有下列四种
       singleton  单例
       prototype  多例
       request  session 与 request和session一样
   (4.@Autowired  自动装配 可以将容器中对应的bean自动注入到属性中
                  单独使用时 该注解下的bean对象 必须是Spring容器中有的
                  而且名字必须相同  
      @Qualifier(" ") 如果容器中有多个对应类型的bean 可以使用@Qualifier
                      指定具体注入哪一个 一般和Autowired搭配使用
   (5.@Resource("name") 功能与上面两个注解搭配使用效果一样
       但是属于手动装配 告诉Spring 把哪一个bean注入进来
   (6.PostConstructor 加在方法上 对象构造后立即执行(相当于添加初始化方法)
      preDestory 加在方法上 对象销毁前执行(相当于添加销毁方法)  

Spring与Junit的整合

1.在测试环境需要创建Spring容器 为了方便在测试环境中不用每个测试方法都去获取容器 
  所以出现了Spring与Junity的整合
方式一:
 (1.导入jar包spring-test-5.0.5.RELEASE.jar
 (2.在测试类上添加:
 // 运行测试时 会自动创建Spring容器
 @RunWith(SpringJUnit4ClassRunner.class) 运行测试时 会自动创建Spring容器
 // 指定配置文件
 @ContextConfiguration("classpath:applicationContext.xml")
方式二:
  (1.导入jar包spring-test-5.0.5.RELEASE.jar
  (2.利用Junit的@Befor@After
  public class SpringTest {
    ClassPathXmlApplicationContext ac;
    @After
    public void after() {
        System.out.println("测试代码后");
        ac.close();
    }
    @Before
    public void before() {
        System.out.println("测试代码前");
        ac = new ClassPathXmlApplicationContext("applicationContext.xml");
    }
    @Test
    public void method1() {
        System.out.println(ac.getBean("per"));
    }
    @Test
    public void method2() {
        System.out.println(ac.getBean("person1"));  
    }
}

Spring的AOP

1.AOP Aspect Oriented Programming
    全程面向切面编程
    是一种编程思想 就像OOP一样
    OOP的核心就是类和对象
    AOP的核心是切面

    其实AOP说的简单点就是将公共代码进行抽取 然后集中编写
    例如:之前使用过的过滤器 拦截器 都是AOP思想
    AOP名词解释
    Joinpoint连接点        可以增强对象
    Pointcut切入点         需要进行增强方法 
    Advice 通知、增强代码
    Target 目标对象 被代理对象
    Weaving 织入 将通知应用到链接点的过程
    代理  代理对象 
    切面  切入点+通知

Spring是如何实现AOP(就是把增强代码插入原有代码)
1.动态代理
        A对象需要被代理
        B对象代理A
        本来直接调用 A对象的方法
        现在换个方式 先调用B对象 B再去调用A对象
        被代理对象(A)必须有实现某个接口
        注意: 没有实现任何接口的对象无法代理 不能增强
2.cglib 
    A对象需要被代理
    B对象代理A
    实现代码增强的原理
    会自动生成被代理类的子类对象
    生成一个A类的子类
    在子类中对代码进行增强
    然后调用父类的原有代码
    注意: 被final修饰的类不能别代理 不能进行增强

如果某个类既没有接口 又被final修饰 SpringAOP就搞不定
这时AspectJ就发挥作用了

用Spring的AOP实现 对方法的调用进行记录 生成记录日志

1.思路:
      首先明确采用AOP
      就是对所有的方法进行增强
      使其具备打印日志的功能
方式一
 (1.在配置文件中添加aop和context约束
 (2.配置 配置文件
<bean name="advice" class="com.lanou.DaoImpl.MyAdvice"></bean>
<aop:config>
    <!--创建切入点-->
    <aop:pointcut expression="execution(* com.lanou.DaoImpl.UserDaoImpl.*(..))" id="point"/>
    <!--将通知织入切点-->
    <aop:advisor advice-ref="advice" pointcut-ref="point"/>
</aop:config> 
<!-- 开启扫描注解 -->
    <context:component-scan base-package="com.
xxx"></context:component-scan>

(3.编写通知类
  public class MyAdvice implements MethodBeforeAdvice,AfterReturningAdvice{
    // 前置通知(前置增强)
    // 参数1 Method 要调用的原始方法
    // 参数2 Obj[] 方法的参数
    // 参数3 Object 被代理对象 真正要执行方法的对象
    @Override
    public void before(Method method, Object[] args, Object target)
    throws Throwable {
        System.out.println(new Date() + " " + target +
         "执行了" + method.getName() + "参数:" +Arrays.toString(args));
        // 执行方法
        //Object object = method.invoke(target, args);  
    }

    // 后置通知
    @Override
    public void afterReturning(Object returnValue, Method method, 
    Object[] args, Object target) throws Throwable {
        System.out.println(new Date() + " " + target + "执行了" +
        method.getName() + "参数:" +Arrays.toString(args) + 
                "返回值" + returnValue);
        // 执行方法
        //Object object = method.invoke(target, args);  
    }
}
方式二
(1.在配置文件中添加aop和context约束
(2.配置 配置文件
<bean name="aroundadvice" class="com.lanou.DaoImpl.MyAroundAdvice"></bean>
<aop:config>
    <aop:pointcut expression="execution(* com.lanou.DaoImpl.UserDaoImpl.*(..))" id="point"/>
    <aop:advisor advice-ref="aroundadvice" pointcut-ref="point"/>
</aop:config>
    <!-- 开启扫描注解 -->
    <context:component-scan base-package="com.xxx"></context:component-scan>

(3.编写通知类
public class MyAroundAdvice implements MethodInterceptor{
    // 环绕通知 方法执行前后都可以知道
    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        Object target = invocation.getThis();
        Object[] arguments = invocation.getArguments();
        Method method = invocation.getMethod();
        System.out.println("环绕增强前");
        // 环绕通知 不会自动调用原始方法
        Object result = method.invoke(target, arguments);
        System.out.println("环绕增强后");
        System.out.println(result);
        return result;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值