24.12.23 注解

发布于:2025-02-11 ⋅ 阅读:(65) ⋅ 点赞:(0)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:util="http://www.springframework.org/schema/util"
       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.xsd
       http://www.springframework.org/schema/util
       http://www.springframework.org/schema/util/spring-util.xsd
">
    <!--component:组件,bean-->
    <!--scan:扫描-->
    <!--开启包扫描,扫描的是base-package路径下的所有类-->
    <!--扫描的时候,查看这些类上面有没有写Spring的注解-->
    <context:component-scan base-package="com.javasm"/>

    <!--读取配置文件-->
    <context:property-placeholder location="test.properties"/>

    <!--直接 把JDK自己的数据类型,装到Spring容器中,当做bean-->
    <!--使用场景:需要给源码中的某些值赋值,或者阅读其他框架的源码-->
    <util:list id="heros">
        <value>莱因哈特</value>

        <value>源氏</value>

        <value>半藏</value>

    </util:list>

    <util:list id="aaaaa">
        <value>努巴尼</value>

        <value>巴黎</value>

        <value>国王大道</value>

    </util:list>

    <util:map id="items">
        <entry key="1001" value="毁灭之刃"/>
        <entry key="2001" value="三相之力"/>
        <entry key="3001" value="破败王者之刃"/>
    </util:map>

    <util:set id="abc">
        <value>第一滴血</value>

        <value>五杀</value>

    </util:set>

    <util:properties id="config">
        <prop key="test1">全屏</prop>

        <prop key="test2">测试</prop>

    </util:properties>

</beans>
@Data
@NoArgsConstructor
@AllArgsConstructor
@Component
public class Game {
    @Value("${game.id}")
    private Integer id;
    @Value("${name}")
    private String name;
    @Value("${price}")
    private Double price;

    //英雄列表
    @Value("#{@heros}")
    private String[] heros;
    //关卡
    @Value("#{@aaaaa}")
    private List<String> levels;
    //背包
    @Value("#{@items}")
    private Map<Integer,String> items;
    //成就
    @Value("#{@abc}")
    private Set<String> achievements;
    //游戏配置
    @Value("#{@config}")
    private Properties gameConfig;
}

自动注入(必会)

        <dependency>
            <groupId>javax.annotation</groupId>

            <artifactId>javax.annotation-api</artifactId>

            <version>1.3.2</version>

        </dependency>
  • byName(找的是Component之类添加进去的bean名称)

    • @Resource
    • java注解,上面的依赖
    //javax.annotation.Resource
    //默认情况下,什么参数也不写,也是按照类型寻找bean对象
    //@Resource
    @Resource(name = "mmm")
    //Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'music' available
    //加了name属性之后,是根据bean的id寻找bean对象
    private Music music;
  • byType
    • @Autowired
org.springframework.beans.factory.annotation.Autowired;

其他注解(了解)

单例

类上面添加注解

@Scope(value = "prototype")//加上后不是单例
@Scope("prototype")
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)

懒加载

@Lazy

初始化和销毁

    @PostConstruct
    public void f1(){
        System.out.println("初始化");
    }

    @PreDestroy
    public void f2(){
        System.out.println("销毁");
    }

延伸注解(必会)

作用和Component一致

@Controller		专门用在Controller层
@Service		专门用在Service层
@Repository		专门用在Dao层(后续没有dao的实现类,使用的是MyBatis,所以很少见)
@Component		通用注解(一般实体类不加入Spring容器)

配置类(必会)

@Configuration
public class WebConfig {
    //当前类是配置类

    //bean对象添加到Spring容器中
    //<bean id="teacher" class="com.javasm.demo.Teacher">
    @Bean//(添加的Spring容器当中的id为方法名)
    public Teacher teacher(){
        Teacher t  = new Teacher();
        t.setId(1001);
        t.setName("李雷");
        return t;
    }
}
@Bean("teacher")//手动设置id

实际应用(必会)

代理模式(了解)

静态代理

在编码阶段,就已经确定,谁是代理类

public interface Programmer {
    void code(Integer money);
}
//真实类
public class Xiaoming implements Programmer{
    @Override
    public void code(Integer money) {
        System.out.println("熬夜写代码,获得工资:"+money);
    }
}
//代理类
public class DongRuan implements Programmer{

    Programmer coder;

    public DongRuan(Programmer coder) {
        this.coder = coder;
    }

    @Override
    public void code(Integer money) {
        System.out.println("收到工资"+money);
        System.out.println("发工资7k");
        //工作
        coder.code(7);
        System.out.println("缴纳五险一金 2k");
        System.out.println("赚了:"+ (money - 7 - 2));
    }
}
public class HuaWei {
    public static void main(String[] args) {
        Programmer programmer = new DongRuan(new Xiaoming());
        programmer.code(30);
    }
}

动态代理

编码阶段,不确定代理的类

编码的时候,不知道我要代理的是谁,我要代理,能代理所有的类

代理的规则,在写代理类的时候就已经确定了,不确定的是接口和真实类

JDK

java中,实现JDK动态代理

public class JDKInvocationHandler implements java.lang.reflect.InvocationHandler {

    //真实类
    private Object target;

    public JDKInvocationHandler(Object target){
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //method 是正在调用的方法
        //invoke执行方法
        //统计性能
        long start = System.currentTimeMillis();
        Object o = method.invoke(target, args);
        long time = System.currentTimeMillis() - start;
        System.out.println("消耗的毫秒数:"+time);
        return o;
    }
}
private static void jdkTest1() {
        //真实类
        PayServiceImpl payServiceImpl = new PayServiceImpl();
        //创建代理对象
        JDKInvocationHandler jdkInvocationHandler = new JDKInvocationHandler(payServiceImpl);
        PayService payService =
                (PayService)Proxy.newProxyInstance(
                        OrderServiceImpl.class.getClassLoader(),
                        new Class[]{PayService.class},
                        jdkInvocationHandler
                );
        payService.del();
    }

Cglib

需要额外引入一个依赖,Spring项目默认已经引入了这个依赖

是一个强大的高性能的代码生成库,在代码运行期间,扩展java类和实现Java接口

public class CglibProxyFactory implements org.springframework.cglib.proxy.MethodInterceptor{
    //真实类
    private Object target;
    public Object getInstance(Object target){
        this.target = target;
        //初始化 真实类
        //创建加速器,创建代理类
        Enhancer enhancer = new Enhancer();
        //设置父类为要代理的类
        enhancer.setSuperclass(this.target.getClass());
        //设置回调方法
        enhancer.setCallback(this);
        //创建并返回代理对象
        return  enhancer.create();
    }


    @Override
    public Object intercept(Object proxy,
                            Method method,
                            Object[] args,
                            MethodProxy methodProxy) throws Throwable {
        //method是调用的方法
        String name = method.getName();
        System.out.println(name+"方法执行之前执行-----"+args);
        //执行方法
        Object result = methodProxy.invokeSuper(proxy, args);
        System.out.println("方法执行之后执行------"+result);
        return result;
    }
}
    public static void main(String[] args) {
        PayServiceImpl payServiceImpl = new PayServiceImpl();
        CglibProxyFactory cglibProxyFactory = new CglibProxyFactory();
        PayService payService = (PayService) cglibProxyFactory.getInstance(payServiceImpl);
        payService.add();
    }

第二天总结

重点

  • 必须会背
@Component
@Controller
@Service
@Repository

@Resource
@Autowired

@Configuration
@Bean
  • 熟练使用注解三层调用
  • 详细描述 @Resource 和 @Autowired区别和共同点

了解

@Scope
@Lazy
@PostConstruct
@PreDestroy
  • 代理模式

网站公告

今日签到

点亮在社区的每一天
去签到