ioc控制反转,最开始主动权在程序猿手中,各个模块依赖在一起。现在主动权在调用者手中,模块和模块之间没有强依赖的关系了,ioc容器进行bean对象的管理。
singleton (单例),prototype(多例),request,session,application,webscoket
静态代理 和 动态代理;springAop的底层原理
角色分析:
抽象角色:一般会使用接口或者抽象类来解决
真实角色:被代理的角色
代理角色:代理真实角色,代理真实角色后,我们一般会做一写附属操作
静态代理,代理类需要实现被代理接口的所有方法,增加了代码
package com.wp.single.daili.staticstate;
import com.wp.single.daili.dynamicstate.UserService;
// 静态代理类Proxy,需要实现UserService中所有的方法
public class Proxy implements UserService {
private UserService userService;
public Proxy() {}
// 进行set方法注入
public Proxy(UserService userService) {
this.userService = userService;
}
@Override
public void add(Integer type) throws Exception {
System.out.println("添加日志");
userService.add(type);
}
}
public static void main(String[] args) throws Exception {
UserService userService = new UserServiceImpl();
Proxy proxy = new Proxy(userService);
proxy.add(1);
}
// 输出:添加日志 以及 + add()方法的内容
静态代理模式的好处:
① 可以使真实角色的操作更加纯粹!,不用去关注一些公共的业务!
② 公共业务也就交给代理角色,实现了业务的分工!
③ 公共业务发生扩展的时候,方便集中管理!
缺点:
一个真实角色就会产生一个代理角色;
动态代理和静态代理角色一样
动态代理的代理类是动态生成的,不是我们直接写好的
动态代理分为两类:基于接口的动态代理;基于类的动态代理
基于接口:JDK动态代理
基于类:cglib
java字节码实现:javasist
package com.example.demo.daili;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class UserProxy implements InvocationHandler {
private UserService userService;
public void setUserService(UserService userService) {
this.userService = userService;
}
// 通过调用getProxy方法生成代理类
public Object getProxy () {
return Proxy.newProxyInstance(this.getClass().getClassLoader(),
userService.getClass().getInterfaces(),this);
}
// 指定方法,在方法的前后进行增强
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("执行方法前");
Object obj = method.invoke(userService,args);
System.out.println("执行方法后");
return obj;
}
}
public static void main(String[] args) {
UserProxy userProxy = new UserProxy();
UserService userService = new UserServiceImpl();
// 进行set方法注入
userProxy.setUserService(userService);
UserService service = (UserService)userProxy.getProxy();
service.save();
}
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="userService" class="com.wupan.test.UserServiceImpl"/>
<bean id="log" class="com.wupan.log.Log"/>
<bean id="afterlog" class="com.wupan.log.AfterLog"/>
<aop:config>
<aop:pointcut id="ponit" expression="execution(* com.wupan.test.UserServiceImpl.*(..))"/>
<aop:advisor advice-ref="afterlog" pointcut-ref="ponit"/>
<aop:advisor advice-ref="log" pointcut-ref="ponit"/>
aop:config>
beans>
package com.wupan.log;
import org.springframework.aop.AfterReturningAdvice;
import java.lang.reflect.Method;
// 实现AfterReturningAdvice,实现后置通知
public class AfterLog implements AfterReturningAdvice {
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
System.out.println("AfterLog类,returnValue:" + returnValue + ",method:" + method+ ",target:" + target);
}
}
// 实现MethodBeforeAdvice方法进行前置通知
public class Log implements MethodBeforeAdvice {
public void before(Method method, Object[] objects, Object o) throws Throwable {
System.out.println("Log类,method:" + method + ",Object:" + o);
}
}
public static void main(String[] args) {
// 加载applicationContext.xml,将对象加载入bean容器中
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
// 获取bean实例
UserService userService = (UserService)applicationContext.getBean("userService");
// 执行UserService中的方法
userService.add();
}
package com.wupan.diy;
// 自定义切面类 Diy01
public class Diy01 {
public void before () {
System.out.println("前置通知Diy01");
}
public void after () {
System.out.println("后置通知Diy01");
}
}
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService = (UserService)applicationContext.getBean("userService");
userService.add();
}
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="userService" class="com.wupan.test.UserServiceImpl"/>
<bean id="diy01" class="com.wupan.diy.Diy01"/>
<aop:config>
<aop:aspect id="aspect01" ref="diy01">
<aop:pointcut id="point" expression="execution(* com.wupan.test.UserServiceImpl.*(..))"/>
<aop:before method="before" pointcut-ref="point"/>
<aop:after method="after" pointcut-ref="point"/>
aop:aspect>
aop:config>
beans>
package com.wupan.zujie;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
// 定义切面注解
@Aspect
public class ZhuJieJava {
// 定义通知 和 切入点
@Before("execution(* com.wupan.test.UserServiceImpl.*(..))")
public void before () {
System.out.println("===before===");
}
@After("execution(* com.wupan.test.UserServiceImpl.*(..))")
public void after () {
System.out.println("===after===");
}
@Around("execution(* com.wupan.test.UserServiceImpl.*(..))")
public void around (ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("方法执行前");
joinPoint.proceed();
System.out.println("方法执行后");
}
}
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="userService" class="com.wupan.test.UserServiceImpl"/>
<bean id="accept" class="com.wupan.zujie.ZhuJieJava"/>
<aop:aspectj-autoproxy/>
beans>
@RestController
public class Controller {
@RequestMapping("/getmessage")
public String getMessage () {
return "ok";
}
}
@Aspect
@Component
@EnableAspectJAutoProxy
public class AspectTest {
@Autowired
HttpServletRequest request;
// 定义环绕通知
@Around("execution(* com.example.demo.controller.Controller.*(..))")
public Object around (ProceedingJoinPoint point) throws Throwable {
String a = request.getParameter("a");
if ("2".equals(a)) {
// 定义条件,不满足则没有权限
return "没有权限!";
} else {
// 有权限执行方法
point.proceed();
}
return "ok";
}
}