本文是我的「Spring学习笔记」第二篇,具体内容可见右侧内容概要,【本文长期更新】

1、静态代理模式

PersonDao.java(接口)

public interface PersonDao {
public void savePerson();
}

PersonDaoImpl(实现类)

public class PersonDaoImpl implements PersonDao {
@Override
public void savePerson() {
// TODO Auto-generated method stub
System.out.println("save Person()...");
}
}

PersonDaoProxy.java

public class PersonDaoProxy implements PersonDao {
PersonDao personDao;
Transaction transaction;
public PersonDaoProxy(PersonDao personDao, Transaction transaction) {
super();
this.personDao = personDao;
this.transaction = transaction;
}
@Override
public void savePerson() {
/**
* 1、开启事务
* 2、执行目标方法
* 3、事务提交
*/
transaction.beginTransaction();
personDao.savePerson();
transaction.commit();
}
}

Transaction

public class Transaction {
public void beginTransaction(){
System.out.println("begin transaction");
}
public void commit(){
System.out.println("commit..");
}
}

ProxyTest

public class ProxyTest {
@Test
public void testProxy(){
PersonDao personDao=new PersonDaoImpl();
Transaction transaction=new Transaction();
PersonDaoProxy proxy=new PersonDaoProxy(personDao, transaction);
proxy.savePerson();
}
}

2、jdk的动态代理

2.1PersonDao.java(接口)

public interface PersonDao {
public void savePerson();
public void updatePerson();
}

2.2PersonDaoImpl.java(实现类)

public class PersonDaoImpl implements PersonDao {
@Override
public void savePerson() {
System.out.println("save Person()...");
}

@Override
public void updatePerson() {
System.out.println("update Person()...");
}
}

2.3Transaction

public class Transaction {
public void beginTransaction(){
System.out.println("begin transaction");
}
public void commit(){
System.out.println("commit..");
}
}

2.4MyInterceptor

public class MyInterceptor implements InvocationHandler {

private Transaction transation;
private Object target;//目标类

public MyInterceptor(Transaction transation, Object target) {
super();
this.transation = transation;
this.target = target;
}

@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
String methodName=method.getName();
if("savePerson".equals(methodName)||"updatePerson".equals(methodName)
||"deletePerson".equals(methodName)){
//开启事务
this.transation.beginTransaction();
method.invoke(target);//调用目标方法
this.transation.commit();
}else{
method.invoke(target);
}
return null;
}
}

2.5测试方法

@Test
public void testJdkProxy(){
/**
* 1、创建一个目标对象
*/
Object target=new PersonDaoImpl();
Transaction transaction=new Transaction();
MyInterceptor interceptor=new MyInterceptor(transaction, target);
PersonDao personDao=(PersonDao) Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(), interceptor);
personDao.savePerson();
}

3、项目二的优化。

3.1PersonDao

public interface PersonDao {
public void savePerson();
public void updatePerson();
}

3.2PersonDaoImpl

public class PersonDaoImpl implements PersonDao {
@Override
public void savePerson() {
System.out.println("save Person()...");
}

@Override
public void updatePerson() {
System.out.println("update Person()...");
}
}

3.3Transaction

public class Transaction  implements Interceptor{
public void interceptor() {
System.out.println("transaction");
}
}

3.4MyInterceptor

public class MyInterceptor implements InvocationHandler {

private List<Interceptor> interceptors;
private Object target;//目标类

public MyInterceptor(Object target, List<Interceptor> interceptors) {
super();
this.interceptors = interceptors;
this.target = target;
}

@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
for (Interceptor interceptor : interceptors) {
interceptor.interceptor();
}
method.invoke(target);
return null;
}
}

3.5Interceptor

public interface Interceptor {
public void interceptor();
}

3.6测试类

public class JdkProxyTest {
@Test
public void testJdkProxy(){
/**
* 1、创建一个目标对象
*/
Object target=new PersonDaoImpl();
Transaction transaction=new Transaction();
List<Interceptor> interceptors = new ArrayList<Interceptor>();
interceptors.add(transaction);
MyInterceptor interceptor=new MyInterceptor(target, interceptors);
PersonDao personDao=(PersonDao) Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(), interceptor);
personDao.updatePerson();
}
}

4、jdkproxy-salary

4.1SalaryManager

public interface SalaryManager {
public void showSalary();
}

4.2SalaryManagerImpl

public class SalaryManagerImpl implements SalaryManager {
@Override
public void showSalary() {
// TODO Auto-generated method stub
System.out.println("您的工资为10W");
}
}

4.3Logger

    public class Logger {
public void Logging(){
System.out.println("日志信息。。。");
}
}

4.4Security

public class Security {
public void security(){
System.out.println("security");
}
}

4.5Privilege

public class Privilege {
private String access;//权限
public String getAccess() {
return access;
}
public void setAccess(String access) {
this.access = access;
}
}

4.6MyInterceptor

public class MyInterceptor implements InvocationHandler {

private Object target;
private Logger logger;
private Privilege privilege;
private Security security;

public MyInterceptor(Object target, Logger logger, Privilege privilege,
Security security) {
super();
this.target = target;
this.logger = logger;
this.privilege = privilege;
this.security = security;
}

@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
/**
* 1、启动日志
* 2、启动安全性的类
* 3、验证权限
* 调用目标对象的目标方法
*/
this.logger.Logging();
this.security.security();
if("wuqingvika".equals(this.privilege.getAccess())){
method.invoke(target);//执行目标方法
}else{
System.out.println("no access!");
}
return null;
}
}

4.7测试方法

@Test
public void testSalary(){
Object target=new SalaryManagerImpl();
Logger logger=new Logger();
Privilege privilege=new Privilege();
privilege.setAccess("wuqingvika");
Security security=new Security();
MyInterceptor interceptor=new MyInterceptor
(target, logger, privilege, security);
SalaryManager sm= (SalaryManager) Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(), interceptor);
sm.showSalary();
}

5、spring-cglibproxy

注:
要导入Jar包哦。cglib-nodep-2.1_3.jar包。

5.1PersonDaoImpl

public class PersonDaoImpl  {

public void savePerson() {
System.out.println("save Person()...");
}

public void updatePerson() {
System.out.println("update Person()...");
}
}

5.2Transaction

public class Transaction {
public void beginTransaction(){
System.out.println("begin transaction");
}
public void commit(){
System.out.println("commit..");
}
}

5.3MyInterceptor

public class MyInterceptor implements MethodInterceptor {

private Transaction transation;
private Object target;//目标类

public MyInterceptor(Transaction transation, Object target) {
super();
this.transation = transation;
this.target = target;
}

/**
* 代码增强类
* @return
*/
public Object createProxy(){
Enhancer enhancer=new Enhancer();
enhancer.setCallback(this);//参数为拦截器
enhancer.setSuperclass(target.getClass());
return enhancer.create();
}

@Override
public Object intercept(Object arg0, Method method, Object[] arg2,
MethodProxy arg3) throws Throwable {
this.transation.beginTransaction();
method.invoke(target);
this.transation.commit();
return null;
}
}

5.4CglibProxyTest

通过cglib产生的代理对象,代理类是目标类的子类

public class CglibProxyTest {
@Test
public void testCglibProxy(){
Transaction transation=new Transaction();
Object target=new PersonDaoImpl();//目标类
MyInterceptor interceptor=
new MyInterceptor(transation, target);
PersonDaoImpl personDaoImpl=
(PersonDaoImpl) interceptor.createProxy();
personDaoImpl.savePerson();
}
}

6、springAOP的第一个例子

注:

此例是需要新添加两个jar包。
aspectjrt.jar和aspectjweaver.jar。
另外:配置文件也要更改哦。

6.1PersonDao

public interface PersonDao {
public void savePerson();
public void updatePerson();
}

6.2PersonDaoImpl

public class PersonDaoImpl implements PersonDao {

@Override
public void savePerson() {
System.out.println("save Person()...");
}

@Override
public void updatePerson() {
System.out.println("update Person()...");

}
}

6.3Transaction

 public class Transaction {
public void beginTransaction(){
System.out.println("begin transaction");
}
public void commit(){
System.out.println("commit..");
}
}

6.4配置文件

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
<bean id="personDao" class="com.wq.aop.xml.PersonDaoImpl"></bean>
<bean id="transaction" class="com.wq.aop.xml.Transaction"></bean>
<aop:config>
<!--
切入点表达式 确定目标类
-->
<aop:pointcut expression="execution(* com.wq.aop.xml.PersonDaoImpl.*(..))"
id="perform"/>
<!--
ref指向的对象就是切面
-->
<aop:aspect ref="transaction">
<aop:before method="beginTransaction" pointcut-ref="perform"/>
<aop:after-returning method="commit" pointcut-ref="perform"/>
</aop:aspect>
</aop:config>

6.5测试类

public class TransactionTest {
@Test
public void testTransaction(){
ApplicationContext context=
new ClassPathXmlApplicationContext("applicationContext.xml");
PersonDao personDao=(PersonDao) context.getBean("personDao");
personDao.savePerson();
}
}

7、Spring通知aop-xml-advise

7.1PersonDao

public interface PersonDao {
public String savePerson();
public void updatePerson();
}

7.2PersonDaoImpl

public class PersonDaoImpl implements PersonDao {
@Override
public String savePerson() {
// int i=1/0;
System.out.println("save Person()...");
return "吴庆加油";
}
@Override
public void updatePerson() {
System.out.println("update Person()...");
}
}

7.3Transaction

public class Transaction {
/**
* 前置通知
* 在目标方法执行之前
* 参数:连接点(joinpoint)
*
*/
public void beginTransaction(JoinPoint joinPoint){
String methodName=joinPoint.getSignature().getName();
System.out.println("连接点的名称:"+methodName);
System.out.println("目标类:"+joinPoint.getTarget().getClass());
System.out.println("begin transaction");
}
public void commit(JoinPoint joinPoint,Object val){
System.out.println("目标方法的返回值:"+val);
System.out.println("commit..");
}

public void finallyMethod(){
System.out.println("final..");
}
public void throwsMethod(JoinPoint joinPoint,Throwable ex){
System.out.println(ex.getMessage());
}
/**
* 环绕通知
* joinPoint.proceed();这个代码如果在环绕通知中不写,则目标方法不再执行
* @throws Throwable
*/
public void aroundMethod(ProceedingJoinPoint joinPoint) throws Throwable{
System.out.println("wquqiqiqi");
joinPoint.proceed();
}
}

7.4配置文件

<bean id="personDao" class="com.wq.aop.xml.PersonDaoImpl"></bean>
<bean id="transaction" class="com.wq.aop.xml.Transaction"></bean>
<aop:config>
<!--
切入点表达式 确定目标类
-->
<aop:pointcut expression="execution(* com.wq.aop.xml.PersonDaoImpl.*(..))"
id="perform"/>
<!--
ref指向的对象就是切面
-->
<aop:aspect ref="transaction">
<!--
前置通知
1、在目标方法执行之前
2、获取不到目标方法的返回值
-->
<aop:before method="beginTransaction" pointcut-ref="perform"/>
<!--
后置通知
1、后置通知可以获取到目标方法的返回值
2、当目标方法抛出异常,后置通知将不再执行
-->
<aop:after-returning method="commit" pointcut-ref="perform" returning="val"/>
<aop:after method="finallyMethod" pointcut-ref="perform"/>
<aop:after-throwing method="throwsMethod" pointcut-ref="perform" throwing="ex" />
<aop:around method="aroundMethod" pointcut-ref="perform"/>
</aop:aspect>

</aop:config>

7.5测试方法

@Test
public void testTransaction(){
ApplicationContext context=
new ClassPathXmlApplicationContext("applicationContext.xml");
PersonDao personDao=(PersonDao) context.getBean("personDao");
personDao.savePerson();
}

8、利用springAOP捕捉异常

8.1PersonDao

public interface PersonDao {
public String savePerson();
public void updatePerson();
}

8.2PersonDaoImpl

public class PersonDaoImpl implements PersonDao {

@Override
public String savePerson() {
int i=1/0;
System.out.println("save Person()...");
return "吴庆加油";
}

@Override
public void updatePerson() {
System.out.println("update Person()...");
Long.parseLong("aaa");
}
}

8.3PersonService

public interface PersonService {
public void savePerson();
public void updatePerson();
}

8.4PersonServiceImpl

public class PersonServiceImpl implements PersonService {

private PersonDao personDao;
public PersonDao getPersonDao() {
return personDao;
}

public void setPersonDao(PersonDao personDao) {
this.personDao = personDao;
}

@Override
public void savePerson() {
personDao.savePerson();
}

@Override
public void updatePerson() {
personDao.updatePerson();
}

}

8.5ExceptionAspect

public class ExceptionAspect {

public void throwException(JoinPoint joinPoint,Throwable ex){
System.out.println(ex.getMessage());
}
}

8.6配置文件

<bean id="personDao" class="com.wq.aop.xml.exception.dao.impl.PersonDaoImpl"></bean>
<bean id="personService" class="com.wq.aop.xml.exception.service.impl.PersonServiceImpl">
<property name="personDao">
<ref bean="personDao"/>
</property>
</bean>
<bean id="exceptionAspect" class="com.wq.aop.xml.exception.except.ExceptionAspect"></bean>
<aop:config>
<aop:pointcut expression="execution(* com.wq.aop.xml.exception.service.impl.*.*(..))"
id="perform"/>
<aop:aspect ref="exceptionAspect">
<aop:after-throwing method="throwException" pointcut-ref="perform" throwing="ex"/>
</aop:aspect>
</aop:config>

8.7测试方法

@Test
public void testException(){
ApplicationContext context=
new ClassPathXmlApplicationContext("applicationContext.xml");
PersonService ps=(PersonService) context.getBean("personService");
ps.updatePerson();
}

9、利用springAOP处理权限

9.1PersonService

public interface PersonService {
public void savePerson();
public void updatePerson();
}

9.2PersonServiceImpl

public class PersonServiceImpl implements PersonService{

@PrivilegeInfo(name="savePerson")
public void savePerson() {
System.out.println("save person中。。。");
}

@PrivilegeInfo(name="updatePerson")
public void updatePerson() {
System.out.println("update person中。。。");
}

}

9.3Privilege

public class Privilege {
private String name;

public String getName() {
return name;
}

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

}

9.4PrivilegeInfo自定义注解

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface PrivilegeInfo {
String name() default "";
}

9.5注解解析器

public class AnnotationParse {
/*
* targetClass 目标类的class形式
* methodName 在客户端调用哪个方法,methodName就代表哪个方法
*/
public static String parse(Class targetClass,String methodName) throws Exception{
String methodAccess="";
Method method=targetClass.getMethod(methodName);
//判断方法上面是否存在PrivilegeInfo注解
if(method.isAnnotationPresent(PrivilegeInfo.class)){
PrivilegeInfo privilegeInfo=method.getAnnotation(PrivilegeInfo.class);
methodAccess=privilegeInfo.name();
}
return methodAccess;
}

}

9.6环绕通知PrivilegeAspect

public class PrivilegeAspect {
/**
* 用户拥有的权限
*/
private List<Privilege> privileges=new ArrayList<Privilege>();

public List<Privilege> getPrivileges() {
return privileges;
}

public void setPrivileges(List<Privilege> privileges) {
this.privileges = privileges;
}

public void isAccessMethod(ProceedingJoinPoint joinpoint) throws Throwable{
/**
* 1、获取访问目标方法应该具备的权限
* 得到
* 1、目标类的class形式
* 2、方法的名称
*/
boolean flag=false;
Class targetClass=joinpoint.getTarget().getClass();
String methodName=joinpoint.getSignature().getName();
//得到访问该方法的权限
String methodAccess=AnnotationParse.parse(targetClass, methodName);
for (Privilege p : privileges) {
if((p.getName()).equals(methodAccess)){
flag=true;
}
}
if(flag){
joinpoint.proceed();
}else{
System.out.println("对不起,你没有访问权限!");
}
}

}

9.7配置文件

<bean id="personService" class="com.wq.privilege.service.impl.PersonServiceImpl"></bean>
<bean id="privilegeAspect" class="com.wq.privilege.aspect.PrivilegeAspect"></bean>
<aop:config>
<aop:pointcut
expression="execution(* com.wq.privilege.service.impl.*.*(..))"
id="perform"/>
<aop:aspect ref="privilegeAspect">
<aop:around method="isAccessMethod" pointcut-ref="perform"/>
</aop:aspect>
</aop:config>

9.8测试类

@Test
public void testPrivilege(){
ApplicationContext context=
new ClassPathXmlApplicationContext("applicationContext.xml");
PrivilegeAspect pa=(PrivilegeAspect) context.getBean("privilegeAspect");
Privilege p1=new Privilege();
p1.setName("savePerson");
Privilege p2=new Privilege();
p2.setName("updatePerson");
pa.getPrivileges().add(p1);
pa.getPrivileges().add(p2);
PersonService personService=(PersonService) context.getBean("personService");
personService.updatePerson();
}

10、springAOP计算每一层方法的调用次数

10.1PersonDaoImpl

personDao省略。

@Override
public void savePerson() {

try {
Thread.sleep(3000L);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("save person...1");
}

10.2PersonServiceImpl

PersonService省略。

public class PersonServiceImpl implements PersonService {

private PersonDao personDao;

public PersonDao getPersonDao() {
return personDao;
}

public void setPersonDao(PersonDao personDao) {
this.personDao = personDao;
}

@Override
public void savePerson() {
this.personDao.savePerson();
}

}

10.3PersonAction

public class PersonAction {
private PersonService personService;

public PersonService getPersonService() {
return personService;
}

public void setPersonService(PersonService personService) {
this.personService = personService;
}

public void savePerson(){
this.personService.savePerson();
}
}

10.4TimeAspect

    public class TimeAspect {
public void ExcutionTime(ProceedingJoinPoint joinPoint) throws Throwable{
String targetClassName=joinPoint.getTarget().getClass().getName();
String methodName=joinPoint.getSignature().getName();
Long preTime=System.currentTimeMillis();
joinPoint.proceed();
Long nextTime=System.currentTimeMillis();
Long executionTime=nextTime-preTime;
System.out.println();
System.out.print("当前的类是:"+targetClassName+",");
System.out.print("当前的方法是:"+methodName+",");
System.out.print("当前方法的开始时间:"+preTime+",");
System.out.println("当前方法的执行时间:"+executionTime);
}
}

10.5配置文件


<bean id="personDao" class="com.wq.dao.impl.PersonDaoImpl"></bean>
<bean id="personService" class="com.wq.service.impl.PersonServiceImpl">
<property name="personDao">
<ref bean="personDao"/>
</property>
</bean>
<bean id="personAction" class="com.wq.action.PersonAction">
<property name="personService">
<ref bean="personService"/>
</property>
</bean>
<bean id="timeAspect" class="com.wq.aspect.TimeAspect"></bean>
<aop:config>
<aop:pointcut expression="execution(* com.wq..*.*(..))" id="perform"/>
<aop:aspect ref="timeAspect">
<aop:around method="ExcutionTime" pointcut-ref="perform"/>
</aop:aspect>
</aop:config>

10.6测试方法

@Test
public void testExecutionTime(){
ApplicationContext context=
new ClassPathXmlApplicationContext("applicationContext.xml");
PersonAction personAction=(PersonAction) context.getBean("personAction");
personAction.savePerson();
}