标签:一起 users lan 注解 修改 封装 npoi 情况 proc
1. 导包4(core/bean/context/spel)+1(logging)+spring-aop包(新版spring需要导入这个包)
2. 为主配置文件引入新的命名空间(约束) Context约束
3. 开启使用注解代理配置文件
<context:component-scan base-package="com.domain"> 指定扫描 com.domain包下面所有类的注解(同时会扫描子包里面的类)
4. 在类中使用注解完成配置
@Component("user")public class User { private String name; private Integer age; public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public String toString() { return "User [name=" + name + ", age=" + age + ", car=" + car + "]"; } }
@Component(“user”)
@Service(“user”) service层
@Controller(“user”) web层
@Repository(“user”) dao层
本质上这四个功能都是一样 只是为了见名知意
@Scope(scopeName=”prototype”) 指定对象的作用范围 同样也是作用在实体上面
@Value("tom")
private String name;
通过反射来为Field赋值 ,但是这样破坏了封装性
通过set方法来赋值 推荐使用
@Value("24") public void setAge(Integer age) { this.age = age; }
1.使用AutoWired 自动装配
@Component("user") public class User { @Autowired private Car car; setCar/getCar ... } @Component class Car{ private String cName; private String color;
get/set ... } 注意:使用自动装配,被装配的字段 也要在容器有 可以没有名字
这种方式有一个坏处:如果匹配多个类型一致的对象,将无法选择具体注入哪一个对象
解决办法:使用 Qualifier("car") 通过该注解来告诉 spring容器自动装配哪个名称的对象
注意:Qualifier和AutoWired要一起使用
@Resource(name="car") 手动注入,指定注入哪个名称的对象
@Resource(name="car") private Car car;
初始化 | 销毁方法
@PostConstruct // 在对象被创建以后调用 相当于配置文件中定义的init-method public void init() { System.out.println("init method"); } @PreDestroy // 在对象被销毁前调用 destory-method public void destory(){ System.out.println("destory method"); }
1.导包 4+2+aop+test
2.配置注解
@RunWith(SpringJUnit4ClassRunner.class) // 帮我们创建容器 @ContextConfiguration("classpath:applicationContext.xml") //指定创建容器时使用的配置文件 public class Student { @Value("wanglei") private String name; @Test public void test() { System.out.println(name); } @Value("24") private Integer age; public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } }
aop思想介绍 横向重复代码 ,纵向抽取
例如:解决乱码问题 管理事务 action拦截器
spring中的aop概念 ------> spring能够为容器中管理的对象生成动态代理对象
以前我们要使用动态代理,需要自己调用下面的方法
Proxy.newProxyInstance(xx,xx,xx) 生成代理对象
现在spring能够帮助我们生成代理对象
1.动态代理(优先) : 被代理对象必须要实现接口,才能产生代理对象,如果没有接口将不能使用动态代理技术。
2.cglib代理(没有接口) : 第三方代理技术,cglib代理可以对任何类生成代理,代理的原理是对目标对象进行继承代理.
但是如果目标对象被final修饰,那么该类无法被cglib代理.
步骤:
1.创建service的接口是实现类
public interface UserService { void save(); void add(); void delete(); void find(); } public class UserServiceIml implements UserService { public void save() { System.out.println("save"); } public void add() { System.out.println("add"); } public void delete() { System.out.println("delete"); } public void find() { System.out.println("find"); } }
2.使用cglib代理生成代理对象
public class Test implements MethodInterceptor{ public UserService getService() { Enhancer en=new Enhancer(); //用于生成代理对象 en.setSuperclass(UserServiceIml.class);//对谁设置代理 en.setCallback(this); //代理要做什么 UserService service = (UserService) en.create();//创建代理对象 return service; } @Override proxyObj 目标类的实例 method 目标类方法的反射实例 arg 参数 methodProxy 代理类实例 public Object intercept(Object proxyObj, Method method, Object[] arg, MethodProxy methodProxy) throws Throwable { System.out.println("打开事务!"); Object returnValue = methodProxy.invokeSuper(proxyObj, arg); System.out.println("提交事务!"); return returnValue; } }
3.测试
public static void main(String[] args) { Test test = new Test(); UserService service = test.getService(); service.save(); }
AOP名词学习
Joinpoint(连接点):目标对象中,所有可以增强的方法
Pointcut(切入点): 目标对象,已经增强的方法
Advice(通知/增强):增强的代码
Target(目标对象): 被代理的对象
Weaving(织入):将通知应用到切入点的过程
Proxy(代理):将通知织入到目标对象之后,形成代理对象
Aspect(切面):切入点 + 通知
步骤:
1.导包4(core + bean + spel + context)+2 + 2(aop + aspect) + 2(allowiance + weaving)
aop包 + aspect包 + aopalliance + weaver
2.准备目标对象
3.准备通知
前置通知 目标方法运行之前调用
后置通知(如果出现异常不会调用) 在目标方法运行之后调用
环绕通知 在目标方法之前和之后都调用
异常拦截通知:如果出现异常,就会调用
后置通知(无论是否出现异常都会调用) :在目标方法运行之后调用
public class MyAdvice { //前置通知 public void before() { System.out.println("前置通知"); } //后置通知 public void afterReturn() { System.out.println("后置通知(如果出现异常不会被调用)"); } //环绕通知 public Object around(ProceedingJoinPoint pjp) throws Throwable{ System.out.println("这是环绕通知之前的部分"); Object proceed = pjp.proceed();//调用目标方法 System.out.println("这是环绕通知之后的部分"); return proceed; } //异常拦截通知 public void afterException() { System.out.println("出现异常了"); } //后置通知 public void after() { System.out.println("后置通知(出现异常也会调用)"); } }
4.配置进行织入,将通知织入目标对象中
准备工作:导入AOP(约束)命名空间
1.配置目标对象 将具体的实现类(而不是接口添加进来) 因为是为 实现类来创建代理对象
<bean name="userService" class="..."></bean>
2.配置通知对象
<bean name="myAdvice" class="...">
3.配置切入点
<aop:pointcut expression="execution(* cn.itcast.service.*ServiceImpl.*(..))" id="pc"/>
execution有以下几种形式
public void cn.itcast.service.UserServiceImpl.save() 具体的某个方法
void cn.itcast.service.UserServiceImpl.save()
* cn.itcast.service.UserServiceImpl.save() 任意返回值
* cn.itcast.service.UserServiceImpl.*() 任意方法名/任意返回值
* cn.itcast.service.*ServiceImpl.*(..) 任意参数/ 任意返回值/ 任意方法名
* cn.itcast.service..*ServiceImpl.*(..) 还会找这个下面的子包
<aop:config> <aop:pointcut expression="execution(* com.domin.*Service.*(..))" id="pc"/> <aop:aspect ref="advice"> <aop:before method="before" pointcut-ref="pc"/> <aop:around method="around" pointcut-ref="pc"/> <aop:after-throwing method="afterException" pointcut-ref="pc"/> <aop:after method="after" pointcut-ref="pc"/> <aop:after-returning method="afterReturn" pointcut-ref="pc"/> </aop:aspect> </aop:config>
调用顺序
1.没有发生异常的情况下
前置通知
这是环绕通知之前的部分
save method
这是环绕通知之后的部分
后置通知(出现异常也会调用)
后置通知(如果出现异常不会被调用)
2.发生异常的情况下
前置通知
这是环绕通知之前的部分
出现异常了
后置通知(出现异常也会调用)
1.导包
2.配置
同样需要加入 <bean name="userService" class="..."></bean> 和 <bean name="myAdvice" class="...">
3.使用注解来实现代理
4.在配置文件中加入 <aop:aspectj-autoproxy></aop:aspectj-autoproxy> 表示开启使用注解完成织入
5.测试
标签:一起 users lan 注解 修改 封装 npoi 情况 proc
原文地址:https://www.cnblogs.com/escapist/p/9038618.html