java aop 属性改变_Spring(二) Spring中的AOP和属性注入

一.AOP(Aspect Oriented Programing)面向切面编程

AOP的终极目标:让我们可以专心做事

下面通过一个例子来介绍AOP的具体使用

案例的要求:使用AOP实现日志记录系统 ,  核心模块  和    增强  单独  开发  ,运行时再组装

首先定义接口和方法

e4d003aeacee92e08682573225aefe30.png

接口和实现类中的代码,我放在一起了,应该比较简单

package demo04.dao;/**

* Created by mycom on 2018/3/5.*/

public interfaceIHelloDao {public voiddoSome();

}

package demo04.dao;

/**

* Created by mycom on 2018/3/5.

*/

public class HelloDaoImpl implements IHelloDao {

public void doSome() {

System.out.println("已经成功加入到DB中了");

}

}

package demo04.service;

/**

* Created by mycom on 2018/3/5.

*/

public interface IHelloService {

public void doSome();

}

package demo04.service;

import demo04.dao.IHelloDao;

/**

* Created by mycom on 2018/3/5.

*/

public class HelloServiceImpl implements IHelloService {

//创建一个Dao的对象

IHelloDao dao;

public IHelloDao getDao() {

return dao;

}

public void setDao(IHelloDao dao) {

this.dao = dao;

}

public void doSome() {

dao.doSome();

}

}

同样在resources下面也要有一个xml文件----applicationContext.xml

这里需要注意一下 class的值只能是实现类的包

然后编写测试类进行测试

@Testpublic voidt1(){

ApplicationContext context=new ClassPathXmlApplicationContext("applicationContextAop.xml");//这里的返回值只能是接口

IHelloService service =(IHelloService) context.getBean("service");

service.doSome();

}

运行的结果

a198b728c0295b648bb6d591a0377f91.png

现在我们要在这句话出现之前,先记录一下日志,出现之后,再出现一句话

首先要创建一个新的包AOP包,并且在包下面写两个类

LoggerAfter是后置增强

LoggerBefore是前置增强

9c6840914ec5eb71513d558f21183159.png

这两个类中的代码如下

package demo04.aop;

import org.springframework.aop.AfterReturningAdvice;

import java.lang.reflect.Method;/**

* Created by mycom on 2018/3/5.*/

public classLoggerAfter implements AfterReturningAdvice {public voidafterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable {

System.out.println("=======after");

}

}

package demo04.aop;

import org.springframework.aop.MethodBeforeAdvice;

import java.lang.reflect.Method;/**

* Created by mycom on 2018/3/5.*/

public classLoggerBefore implements MethodBeforeAdvice {public voidbefore(Method method, Object[] objects, Object o) throws Throwable {

System.out.println("日志记录");

}

}

在xml中配置,在配置xml是要给AOP添加一个约束

测试类

import demo04.service.HelloServiceImpl;

import demo04.service.IHelloService;

import demo05.MyCollection;

import demo05.Student;

import org.junit.Test;

import org.springframework.context.ApplicationContext;

import org.springframework.context.support.ClassPathXmlApplicationContext;/**

* Created by mycom on 2018/3/3.*/

public classTest20180305 {

@Testpublic voidt1(){

ApplicationContext context=new ClassPathXmlApplicationContext("applicationContextAop.xml");//这里的返回值只能是接口

IHelloService service =(IHelloService) context.getBean("service");

service.doSome();}

}

a8ed04d4e6163d76cd263bd67ec1774d.png

在这里和要介绍两个单词的意思

advice :通知

advisor:顾问

顾问可以包装通知

execution(【modifiers-pattern?】 访问修饰符

ret-type-pattern 返回值类型

【declaring-type-pattern?】 全限定性类名

name-pattern(param-pattern) 方法名(参数名) 包名.类型名.方法名

【throws-pattern?】) 抛出异常类型

public void doLog(String log){

}

方法签名

切入点表达式要匹配的对象就是目标方法的方法名。所以,execution表达式中明显就是方法的签名。

注意:表达式中加[]的部分表示可省略部分,各部分间用空格分开。在其中可以使用以下符号:

符号 意义

* 0至多个任意字符

.. 用在方法参数中,表示任意多个参数

用在包名后,表示当前包及其子包路径

+ 用在类名后,表示当前类及其子类

用在接口后,表示当前接口及其实现类

案例:

execution(public * *(..)) 指定切入点为:任意公共方法

execution(* set*(..)) 指定切入点为:任何一个以"set"开始的方法

二.给属性注入值(四种)

1.setter方法注入(就是在bean节点下有property节点给里面的属性值赋值

2.构造注入

3.p命名空间注入(使用前要先要在Spring配置文件中引入p命名空间xmlns:p="http://www.springframework.org/schema/p")

这里的两种我写在一起了

首先写一个学生类,车类,MyCollection

package demo05;/**

* Created by mycom on 2018/3/5.*/

public classStudent {privateString name;privateInteger age;privateCar car;publicStudent() {

}publicStudent(String name, Integer age) {this.name =name;this.age =age;

}publicString getName() {returnname;

}public voidsetName(String name) {this.name =name;

}publicInteger getAge() {returnage;

}public voidsetAge(Integer age) {this.age =age;

}publicCar getCar() {returncar;

}public voidsetCar(Car car) {this.car =car;

}

}

package demo05;/**

* Created by mycom on 2018/3/5.*/

public classCar {privateString color;privateString brand;publicString getBrand() {returnbrand;

}public voidsetBrand(String brand) {this.brand =brand;

}publicString getColor() {returncolor;

}public voidsetColor(String color) {this.color =color;

}

}

在xml中的配置

最后编写测试类

以p命名空间注入为例进行测试

import demo04.service.HelloServiceImpl;

import demo04.service.IHelloService;

import demo05.MyCollection;

import demo05.Student;

import org.junit.Test;

import org.springframework.context.ApplicationContext;

import org.springframework.context.support.ClassPathXmlApplicationContext;/**

* Created by mycom on 2018/3/3.*/

public classTest20180305 {

@Testpublic voidt1(){

ApplicationContext context=new ClassPathXmlApplicationContext("applicationContextCon.xml");

Student service2 =(Student) context.getBean("stu");

System.out.println(service2.getName());

} }

4.集合注入

再写一个MyCollection类

package demo05;

import java.util.*;/**

* Created by mycom on 2018/3/5.*/

public classMyCollection {privateString[] array;private Listlist;private Set set;private Mapmap;privateProperties properties;publicMyCollection() {

System.out.println("创建对象===========");

}public MyCollection(String[] array, List list, Set set, Mapmap, Properties properties) {this.array =array;this.list =list;this.set = set;this.map =map;this.properties =properties;

}@Override

public String toString() {

return "MyCollection{" +

"array=" + Arrays.toString(array) +

", list=" + list +

", set=" + set +

", map=" + map +

", properties=" + properties +

'}';

}

publicString[] getArray() {returnarray;

}public voidsetArray(String[] array) {this.array =array;

}public ListgetList() {returnlist;

}public void setList(Listlist) {this.list =list;

}public SetgetSet() {return set;

}public void setSet(Set set) {this.set = set;

}public MapgetMap() {returnmap;

}public void setMap(Mapmap) {this.map =map;

}publicProperties getProperties() {returnproperties;

}public voidsetProperties(Properties properties) {this.properties =properties;

}

}

小明

小兰

list1

list2

set1

set2

01

02

001

002

import demo04.service.HelloServiceImpl;

import demo04.service.IHelloService;

import demo05.MyCollection;

import demo05.Student;

import org.junit.Test;

import org.springframework.context.ApplicationContext;

import org.springframework.context.support.ClassPathXmlApplicationContext;/**

* Created by mycom on 2018/3/3.*/

public classTest20180305 {

@Testpublic voidt1(){

ApplicationContext context=new ClassPathXmlApplicationContext("applicationContextCon.xml");//返回的类型只能是接口

MyCollection service =(MyCollection) context.getBean("collection");

System.out.println(service);}

}

三.Spring中bean是单例的问题

单例:一个类在内存中只能有一个对象。

单利满足的三个条件:

1.构造私有

2.是有的静态变量,变量的类型就是当前类的类型

3.提供一个静态方法

在xml中配置实现单例还是多例的属性是scope

他的值有两个singleton  单例

prototype 多例

在上面的集合注入的例子中进行改动,并且如果MyCollection中有toString方法,也要注释掉,可以更直观的看到,如下

da26aaa48fe7fc33952ab1a124d1a786.png

然后我们来编写测试方法进行测试

import demo04.service.HelloServiceImpl;

import demo04.service.IHelloService;

import demo05.MyCollection;

import demo05.Student;

import org.junit.Test;

import org.springframework.context.ApplicationContext;

import org.springframework.context.support.ClassPathXmlApplicationContext;/**

* Created by mycom on 2018/3/3.*/

public classTest20180305 {

@Testpublic voidt1(){

ApplicationContext context=new ClassPathXmlApplicationContext("applicationContextCon.xml");

MyCollection service=(MyCollection) context.getBean("collection");

System.out.println(service);

MyCollection service2=(MyCollection) context.getBean("collection");

System.out.println(service2);

}

}

运行结果

73a8da7b6f4d379c1b06ca06da293594.png

从运行结果来看,两次创建的对象的指针不同,创建的是两个对象,这是多例

线面再来看单例,将scope的属性值改为singleton

此时的运行结果如下

817e2a1fb3660fe71443740eca4f0036.png

他只创建了依次对象,实现了单利

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值