Java 之 Spring 注解配置和 AOP

注解配置

当我们的项目越来越复杂时,配置文件也会变得复杂
影响开发效率
所以 Spring 提供了注解方式来配置 bean

准备工作

使用注解准备工作
    1.添加 Context 命名空间   
      xmlns:context="http://www.springframework.org/schema/context"
      xsi:schemaLocation="http://www.springframework.org/schema/beans   
      http://www.springframework.org/schema/beans/spring-beans.xsd
      http://www.springframework.org/schema/context 
      http://www.springframework.org/schema/context/spring-context-4.3.xsd"
    2.添加 aop jar 包      spring-aop-5.0.5.RELEASE.jar
    3.扫描注解
      <context:component-scan base-package="需要扫描的包的包名"></context:component-scan>
注解详细
    1.@Component
      例如:给Person 类加上该注解等同于在配置文件中添加了"person" class="com.xxx.entity.Person">
      如果没有指定 bean 名字,默认是类名以小写开头
      指定名字:@Component("name")
    2.@Component 的衍生标签
      @Service          对应 Service 业务逻辑层
      @Controller       对应 Action/Servlet
      @Repository       对应数据库相关(Dao)
    这三个子标签作用和 @Component 一样,但是更加语义化,更符合 JavaEES 分层思想
    3.@Scope 用来控制 bean 的作用域
      @Scope(scopeName="singleton")
      @Scope(scopeName="prototype")
      @Scope(scopeName="request")
      @Scope(scopeName="session")
    4.注入属性
      @Value("值")
      可以写在属性上,但是会破坏对象的封装性(建议写在 set 方法上)
         @Value("(*^__^*) 嘻嘻……")
         private String name;
      可以写在 set 方法上
         @Value("男")
         public void setGender(String gender) {
             this.gender = gender;
         }
    5.@Autowired 自动装配,可以将容器中对应 bean 自动注入到属性中
      @Qualifier 如果容器中有多个对应类型的 bean, 可以使用@Qualifier指定具体注入哪一个
                 和 @Autowired 搭配使用
    6.@Resource 手动装配,告诉 Spring, 注入哪个 bean
                @Resource(name = "myHouse")
    7.@PostConstruct 对象构造后立即执行
    8.@PreDestroy 对象销毁前执行
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;

//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
//import org.springframework.stereotype.Controller;
//import org.springframework.stereotype.Repository;
//import org.springframework.stereotype.Service;

@Component
// @Service("test")
// @Controller("test")
// @Repository("test")
public class Person {
    @Value("(*^__^*) 嘻嘻……")
    private String name;
    private String gender;
    private Integer age;

    @Resource(name = "myHouse")
    private House house;

    public Person() {
        super();
        System.out.println("无参");
    }

    public Person(String name, String gender, Integer age) {
        super();
        System.out.println("有参");
        this.name = name;
        this.gender = gender;
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

    public String getGender() {
        return gender;
    }

    @Value("男")
    public void setGender(String gender) {
        this.gender = gender;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public House getHouse() {
        return house;
    }

    public void setHouse(House house) {
        this.house = house;
    }

    @Override
    public String toString() {
        return "Person [name=" + name + ", gender=" + gender + ", age=" + age + ", house=" + house + "]";
    }

    @PostConstruct // 构造函数调用之后执行
    public void init() {
        System.out.println("前置方法");
    }

    @PreDestroy // 销毁之前执行的方法
    public void destroy() {
        System.out.println("后置方法");
    }

}

Spring 与 Junit 整合测试

在测试环境需要手动创建 Spring 容器   管理生命周期
SpringTest 就是为了方便在测试环境获取容器出现的
1.导入 jar 包
2.在测试类上添加
  // 运行测试时,会自动创建 Spring 容器
  @RunWith(SpringJUnit4ClassRunner.class)
  // 指定配置文件
  @ContextConfiguration("classpath:applicationContext.xml")
// 运行测试时,会自动创建 Spring 容器
@RunWith(SpringJUnit4ClassRunner.class)
// 指定配置文件
@ContextConfiguration("classpath:applicationContext.xml")
public class SpringTest {
    @Resource(name="person")
    Person person;
    @Test
    public void method() {
        System.out.println(person);
    }
}
Test 环境和 Web 环境的区别
Test 不会自动创建容器,所以无法使用 @Autowired
Web 环境中 Spring 可以跟随项目启动

AOP

AOP Aspect Oriented Programming
全程面向切面编程,是一种编程思想,就像 OOP 一样
OOP 的核心就是类和对象
AOP 的核心就是切面

其实 AOP 说的简单点就是讲公共代码进行抽取
集中编写
例如:使用过得过滤器,拦截器,都是 AOP 思想

AOP名词解释

Joinpoint连接点        可以增强对象
Pointcut切入点         需要进行增强方法 
Advice                通知、增强代码
Target                目标对象 被代理对象
Weaving               织入 将通知应用到链接点的过程
代理                   代理对象 
切面                   切入点+通知

Spring 实现 AOP 原理

1.动态代理
    A 对象需要被代理
    B 对象来代理 A
    本来直接调用 A 对象的方法
    现在换个方式先调用 B 对象,然后 B 对象再去调用 A 对象
    被代理对象 A 必须有实现某个接口
    注意:没有实现任何接口的对象无法代理

2.cglib
    A 对象需要被代理
    实现代码增强的原理
    会自动生成被代理类的子类对象
    生成一个 A 类对象的子类
    在子类中对代码进行增强
    然后调用父类的原有代码
    注意:被 final 修饰的类不能被代理,不能进行增强

如果某个类即没有接口,又被 final 修饰 SpringAOP 就搞不定了
这时 AspectJ 发挥作用了

你可能感兴趣的:(spring,java,工作,bean,aop)