使用注解配置spring

使用注解配置spring

1.     导包  4+2+1

aop


2.     导入约束文件

       xmlns:context=http://www.springframework.org/schema/context
http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context.xsd

3.     指定扫描的包

<context:component-scan base-package="cn.hd.annotation"></context:component-scan>

4.     为类证明注解

在类上面声明注解

@Component("user")   // 相当于.xml  bean  name=user class=cn.hd.annotation.User
public class User {
    private String name;
    private Integer age;
    private String address;
private Car car;
为了解决所有的bean类都是同一个注解,导致层次不清晰 提出了这是那个注解
  @Controller("user")//web层
    @Service("user")//service层
@Repository("user")//dao层

没有强制要求,都可以用,提倡按照他的本意去注解

修改Scope属性

  @Scope(scopeName = "prototype")//singleton | prototype 单例和多例

属性注入

(1)     值类型:注解写在属性上面同时也可以写在set方法上面

@Value("王小二")
    private String name;
    @Value("18")
    private Integer age;
    @Value("河南")
private String address;

(2)     引用类型

/* @Autowired//自动装配  如果只有有个对象 自动装配
    @Qualifier("car2")*/   //自动装配是有多个对象就要指定是哪个对象 与自动装配结合使用
    @Resource(name = "car")//直接指定配置哪个对象
private Car car;

(3)     创建对象后就执行的方法

@PostConstruct
    public void init(){
        System.out.println("对象创建后自动执行");
    }
    @PreDestroy
    public void destroy(){
        System.out.println("对象销毁前执行的");
    }

Spring结合junit

1.     导包

test



2.     书写测试代码

@RunWith(SpringJUnit4ClassRunner.class)//结合Junit测试
@ContextConfiguration("classpath:cn/hd/annotation/applicationContext.xml")//读取配置文件

由于原来使用的是ApplicationContext对象 读取配置文件和获得bean对象

但是现在没有了 又想获得对象

  @Resource(name = "user")
private User user;

spring aop

aop:面向切面编程,纵向重复横向抽取


代理:生活中的实例找明星拍戏,上综艺,唱歌。。。。。直接找明星 说明明星太小

如果有点名气,那就不能直接访问,必须先通过访问明星的经纪人然后经纪人访问明星经纪人就是明星的代理,放在程序当中有一个目标对象有一个代理对象。你想访问目标对象必须先通过代理对象由代理对象决定访问目标对象。Java提供了一个类Proxy能实现代理

Spring Aop

利用了代理

利用了代理技术 主要应用于在service层的事务管理

 

Spring实现aop有两种办法

(1) 动态代理:被代理对象必须实现接口,如果没有接口则不能实现动态代理。

(2) cglib代理:第三方的代理技术。任何类都可以实现代理使用继承的机制实现代理  所以被代理对象不能被final修饰

 

手动实现动态代理

      准备一个UserService   UserServiceImpl

准备一个获得UserService代理对象的类

1.     获取代理对象通过调用proxy的newPorxoyInstance方法  传递三个参数

(1)本类的加载器(2).代理对象的接口(实现类获得接口)(3).this这样得到了一个代理对象

1.     实现代理对象的方法 让这个类实现InvoiceHandler接口实现他的方法inVoke(代理的对象 调用的方法 方法的参数)

被代理的对象方法还是要被调用 所有调用method。Invoke()两个参数一个是被代理对象,参数给该类加上一个属性被代理对象 并给该类 添加构造函数。在调用被代理对象方法的前后。可以加上对应的内容

public class UserServiceProxyFactory implements InvocationHandler{
   private UserService userService;

    public UserServiceProxyFactory(UserService userService) {
        this.userService = userService;
    }

    public UserService getUserServiceProxy(){
        UserService userServiceProxy= (UserService) Proxy.newProxyInstance(UserServiceProxyFactory.class.getClassLoader(),
         UserServiceImpl.class.getInterfaces(),this);
    return userServiceProxy;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("开启事务");
        Object invoke =method.invoke(userService,args);
        System.out.println("关闭事务");
        return invoke;
    }
}

cglib代理

public class UserServiceProxyFactory2 implements MethodInterceptor{
    public UserService getUserServiceProxy(){
        Enhancer enhancer = new Enhancer();//帮助我们生成代理对象
        enhancer.setSuperclass(UserServiceImpl.class);//设置对谁进行代理
        enhancer.setCallback(this);//回调方法
        UserService userServiceProxy  = (UserService) enhancer.create();
        return userServiceProxy;
    }
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("开启事务");
        Object o1 = methodProxy.invokeSuper(o,objects);
        System.out.println("关闭事务");
        return o1;
    }
}

Spring Aop 配置

 7个专业名词

 JoinPoint(连接点) 被代理对象所有可以增强的方法

 PointCut(切入点)已经增强的方法

 Advice  (通知) 增强的内容

Target  (目标对象)被代理的对象

Waving  (织入)将通知织入到目标对象中

Proxy (代理) 代理对象 将通知织入到目标对象后就变成代了对象

Aspect  (切面)通知+切入点


1.导包 4+2   +2+2 spring(aop aspect) spring(依赖包)


2.     准备目标对象  UserServiceImpl

3.     准备通知

4.     配置applicationContext.xml文件

导入约束

直接打入<aop:conf 如果有提示 直接打回车会自动导入约束

没有提示就手动导入

5.     配置切入:

配置切入点

配置切面:将通知织入到对应的切入点

多种方式切入总共有五总 切入方式

1.     在目标对象方法前调用

  <aop:before method=”通知中增强的代码” pointcut-ref=“切入点”></aop before >
<aop:before method="before" pointcut-ref="pc"></aop:before>

2.     在目标对象方法后调用(没有异常)

<aop:after method="after" pointcut-ref="pc"></aop:after>
3.在目标对象方法后调用(不管有没有异常)

<aop:around method="around" pointcut-ref="pc"></aop:around>

4.     在目标对象方法前后调用代码(特殊,在通知中的方法

ProceedingJoinpoint参数如果有异常方法后的不调用)

<aop:after method="afterReturning" pointcut-ref="pc"></aop:after>
5.只有在目标对象方法出现异常是调用
<aop:after-throwing method="throwException" pointcut-ref="pc"></aop:after-throwing>

  <!--配置aop切入-->
        <aop:config>
              <!--配置切入点-->
                <!--
                public void cn.hd.springProxy.impl.UserServiceImpl.add()
                        * cn.hd.springProxy.impl.UserServiceImpl.add()//public 可以省略 返回只可以是任意类型
                      * cn.hd.springProxy.impl.*ServiceImpl.*(..)//所有方法可以用*来代替 所有参数可以用..代替 所有Service *Service代替
                      * cn.hd.springProxy.impl..*ServiceImpl.*(..)//不常用
                -->
                <aop:pointcut id="pc" expression="execution( * cn.hd.springProxy.impl.*ServiceImpl.*(..))"></aop:pointcut>
                <!--配置切面 织入通知-->
                <aop:aspect ref="myAdvice">
                        <aop:before method="before" pointcut-ref="pc"></aop:before>
                </aop:aspect>

        </aop:config>





























猜你喜欢

转载自blog.csdn.net/leizhenjiang/article/details/80931896