spring复习

(一)初步使用

  1. pom.xml

    <!--spring依赖-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.1.5.RELEASE</version>
    </dependency>
    
  2. 创建spring.xml,并注入bean

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           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.xsd">
        <!-- 注入bean -->
        <bean id="TestServiceImpl" class="com.lr.day5.impl.TestServiceImpl"/>
    </beans>
    
  3. 创建测试类,获取读取配置文件,并获取bean

    // 读取xml配置文件
    ClassPathXmlApplicationContext c = new ClassPathXmlApplicationContext("spring.xml");
    // 获取bean
    //TestService bean = (TestService) c.getBean("TestServiceImpl");
    //TestService bean = c.getBean(TestService.class); //如果ioc有多个bean实现了该接口会报错,spring不知道返回给你哪个bean
    TestService bean = c.getBean("TestServiceImpl", TestService.class);
    bean.say();
    

(二)使用set或构造器为bean赋值

  1. xml中

    <!-- 1.使用set方法为bean赋值 -->
    <bean id="user1" class="com.lr.day5.bean.User">
        <property name="no" value="1"/>
        <property name="name" value="张三1"/>
    </bean>
    <!-- 2.使用构造器为bean赋值 -->
    <bean id="user2" class="com.lr.day5.bean.User">
        <constructor-arg name="no" value="2"/>
        <constructor-arg name="name" value="张三2"/>
    </bean>
    <!-- 3.使用构造器和set方法混合为bean赋值 -->
    <bean id="user3" class="com.lr.day5.bean.User">
        <constructor-arg name="no" value="3"/>
        <property name="name" value="张三3"/>
    </bean>
    <!-- 4.为bean赋值引用,引用ioc的其他bean -->
    <bean id="superUser1" class="com.lr.day5.bean.SuperUser">
        <constructor-arg name="id" value="1"/>
        <constructor-arg ref="user1"/>
    </bean>
    <!-- 5.为bean赋值引用,临时创建bean -->
    <bean id="superUser2" class="com.lr.day5.bean.SuperUser">
        <constructor-arg name="id" value="2"/>
        <constructor-arg name="user">
            <bean class="com.lr.day5.bean.User">
                <property name="no" value="04"/>
                <property name="name" value="李四"/>
            </bean>
        </constructor-arg>
    </bean>
    
  2. 获取属性

    // 读取xml配置文件
    ClassPathXmlApplicationContext c = new ClassPathXmlApplicationContext("spring.xml");
    //1.使用set方法为bean赋值
    User u1 = c.getBean("user1", User.class);
    System.out.println(u1);
    //2.使用构造器为bean赋值
    User u2 = c.getBean("user2", User.class);
    System.out.println(u2);
    //3.使用构造器和set方法混合为bean赋值
    User u3 = c.getBean("user3", User.class);
    System.out.println(u3);
    //4.为bean赋值引用,引用为ioc的其他bean
    SuperUser superUser1 = c.getBean("superUser1", SuperUser.class);
    System.out.println(superUser1);
    //5.为bean赋值引用,引用为临时创建的bean
    SuperUser superUser2 = c.getBean("superUser2", SuperUser.class);
    System.out.println(superUser2);
    
  3. 通过set赋值的方式,需要有无参构造器。

(三)作用域

  • 原型模式(prototype):相当于反射新建一个bean返回,多例模式

    <bean id="TestServiceImpl" class="com.lr.day5.impl.TestServiceImpl" scope="prototype"/>
    
  • 单例模式(singleton):单例模式,spring默认单例模式

    <bean id="TestServiceImpl" class="com.lr.day5.impl.TestServiceImpl" scope="singleton"/>
    

如果使用了多例/原型模式

// 读取xml配置文件
ClassPathXmlApplicationContext c = new ClassPathXmlApplicationContext("spring.xml");
// 获取bean
TestService bean1 = c.getBean("TestServiceImpl", TestService.class);
TestService bean2 = c.getBean("TestServiceImpl", TestService.class);
sout(bean1 == bean2); // => false

(四)IOC基于注解实现

  1. xml中添加名称空间

    xmlns:context="http://www.springframework.org/schema/context"
    
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd
    
  2. 开启扫描

    <!-- 开启注解扫描 -->
    <context:component-scan base-package="com.lr.day5"/>
    
  3. bean上添加注解自动注入IOC容器

    @Component(组件上使用)、@Repository(dao层)、@Service(服务层)、@Controller(控制器)都可以

  4. 字段上添加注解@Autowired获取IOC中的bean

  5. 查看其他注解和@Component的区别,@Repository、@Service、@Controller注解都是被@Component所标识,所以本质上没多大区别。

  6. @Component的value属性:相当于xml的bean设置id

    如果没有指定value,默认设置bean的id为类名的驼峰形式

  7. @Autowired:注入bean,相当于通过class获取bean – c.getBean(TestService.class);,value属性是boolean值,true表示没找到bean抛异常(默认值),false表示没找到返回null。

  8. @Scope:相当于xml的bean设置scope,加在类上,配合@Component等注解使用。

  9. @Qualifier:翻译为限定词或限定符,相当于通过id获取bean – c.getBean(TestService.class);,和@Autowired配合使用。

    @Autowired
    @Qualifier("testServiceImpl")
    TestService testService;
    
  10. @Resource:根据字段名去获取ioc中的bean,获取不到就通过class去获取。如果指定name值,就通过name去获取ioc的bean。(并且这个是java提供的,一般使用@Autowired)

(五)AOP

  1. 引入maven

    <!--spring+aop依赖-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aop</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjrt</artifactId>
        <version>1.6.12</version>
    </dependency>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.6.12</version>
    </dependency>
    <dependency>
        <groupId>cglib</groupId>
        <artifactId>cglib</artifactId>
        <version>2.2</version>
    </dependency>
    
  2. 配置名称空间

    xmlns:aop="http://www.springframework.org/schema/aop"
    
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop.xsd
    
  3. 创建切面类

    public class PointCut {
        public void after(JoinPoint joinPoint) throws Throwable {
            System.out.println("after~");
        }
    
        public void before(JoinPoint joinPoint) throws Throwable {
            System.out.println("before~");
        }
    
        public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
            System.out.println("around~");
            return proceedingJoinPoint.proceed();
        }
    
        public void afterThrowing(JoinPoint joinPoint) throws Throwable {
            System.out.println("afterThrowing~");
        }
    
        public void afterReturning(JoinPoint joinPoint) throws Throwable {
            System.out.println("afterReturning~");
        }
    }
    
  4. 配置切面bean

    <!-- 注入切面bean -->
    <bean id="aspect" class="com.lr.day5.aop.PointCut"/>
    

    aspect翻译为切面

  5. 配置aop,先配置切入点(被增强的方法),再配置切面

    <aop:config>
        <!-- 配置切入点 -->
        <aop:pointcut id="pointcut" expression="execution(* com.lr.day5.impl.TestServiceImpl.*(..))"/>
        <!-- 配置切面 -->
        <aop:aspect ref="aspect">
            <aop:before method="before" pointcut-ref="pointcut"/>
            <aop:after method="after" pointcut-ref="pointcut"/>
            <aop:around method="around" pointcut-ref="pointcut"/>
            <aop:after-throwing method="afterThrowing" pointcut-ref="pointcut"/>
            <aop:after-returning method="afterReturning" pointcut-ref="pointcut"/>
        </aop:aspect>
    </aop:config>
    

    expression表达式:

    execution(* com.lr.day5.impl.TestServiceImpl.*(..))
        1     2         3						 4	5
    1:声明表达式()
    2:方法的权限访问符
    3:类的全路径
    4:方法名
    5:参数
    上面的表达式表示:com.lr.day5.impl.TestServiceImpl类的所以方法
    

(六)AOP基于注解实现

  1. 导入maven

    <!-- aop注解依赖 -->
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjrt</artifactId>
        <version>1.6.12</version>
    </dependency>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.6.12</version>
    </dependency>
    <dependency>
        <groupId>cglib</groupId>
        <artifactId>cglib</artifactId>
        <version>2.2</version>
    </dependency>
    
  2. xml启用对@AspectJ注解的支持

    <!-- 启用对于@AspectJ注解的支持 -->
    <aop:aspectj-autoproxy/>
    
  3. 创建切面类

    @Aspect
    @Component
    public class PointCut {
    	//execution表达式
        private static final String POINT_CUT = "execution(* com.lr.day5.impl.TestServiceImpl.*(..))";
    
        @After(POINT_CUT)
        public void after(JoinPoint joinPoint) throws Throwable {
            System.out.println("after~");
        }
    
        @Before(POINT_CUT)
        public void before(JoinPoint joinPoint) throws Throwable {
            System.out.println("before~");
        }
    
        @Around(POINT_CUT)
        public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
            System.out.println("around~");
            return proceedingJoinPoint.proceed();
        }
    
        @AfterThrowing(POINT_CUT)
        public void afterThrowing(JoinPoint joinPoint) throws Throwable {
            System.out.println("afterThrowing~");
        }
    
        @AfterReturning(POINT_CUT)
        public void afterReturning(JoinPoint joinPoint) throws Throwable {
            System.out.println("afterReturning~");
        }
    }
    

(七)使用工厂模式和动态代理模式简单模拟IOC和AOP

  1. 创建被代理接口

    public interface TestService {
        void say();
    }
    
  2. 创建被代理类

    @Service
    public class TestServiceImpl implements TestService {
        @Override
        public void say() {
            System.out.println("hello");
        }
    }
    
  3. 创建代理类

    public class MyProxy implements InvocationHandler {
        private Object obj;
    
        public MyProxy(Object obj) {
            this.obj = obj;
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            Object o = null;
            System.out.println("增强代码~~~");
            o = method.invoke(obj, args);
            System.out.println("增强代码~~~");
            return o;
        }
    }
    
  4. 创建Bean工厂模拟IOC

    public class BeanFacory {
        private static Map<String, String> IOC = new HashMap<>();
    
        static {
            IOC.put("test1", "com.lr.day5.impl.TestServiceImpl");
            IOC.put("test2", "com.lr.day5.impl.TestServiceImpl2");
        }
    
        public static <T> T getBean(String id) throws Exception {
            String className = IOC.get(id);
            Class<?> clazz = Class.forName(className);
            Object o = clazz.getDeclaredConstructor().newInstance();
            MyProxy myProxy = new MyProxy(o);
            Object proxy = Proxy.newProxyInstance(myProxy.getClass().getClassLoader(), clazz.getInterfaces(), myProxy);
            return (T) proxy;
        }
    }
    
  5. 测试

    @Test
    void getBean() throws Exception {
        TestService bean = BeanFacory.getBean("test1");
        bean.say();
    }
    
    //输出
    增强代码~~~
    hello
    增强代码~~~
    
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值