初学Spring03

ApplicationContext实现类

  1. ClassPathXmlApplicationContext:直接引用resources文件路径下的配置文件
  2. FileSystemXmlApplicationContext:文件磁盘地址
  3. AnnotationConfigApplicationContext

getBean

如果只有一个对象直接使用这个getBean(Class)
多个用getBean(“id”)需要强转

配置数据源

数据源提高性能
实例化数据源,初始化部分连接资源
使用连接资源从数据源中获取
使用完后归还给数据源

常见数据源 DBCP, C3P0,BoneCP,Druid

什么是数据源? 它可以被看做一个数据缓冲区 可以大大提升性能
数据库连接池的意义在于,能够重复利用数据库连接

配置C3P0

  <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.20</version>
        </dependency>
        <dependency>
            <groupId>c3p0</groupId>
            <artifactId>c3p0</artifactId>
            <version>0.9.1.2</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.23</version>
        </dependency>

连接数据库读取数据

  public void test1() throws Exception {
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setDriverClass("com.mysql.cj.jdbc.Driver");
        dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test?serverTimezone=UTC");
        dataSource.setUser("root");
        dataSource.setPassword("111111");
        Connection connection = dataSource.getConnection();
        System.out.println(connection);
        connection.close();

    }

连接数据库时 因为Server时区不同会报错需要在路径后加上serverTimezone=UTC

而这种方法让数据池与单一数据库过分耦合 非常不方便

使用配置文件加载使耦合变松

public void test3() throws Exception {
        //读取配置文件
        ResourceBundle rb = ResourceBundle.getBundle("jdbc");   //写resources下的内容的基名 只要写名字不用后缀,切路径名从resources开始
       

    }

用命名空间导入properties文件

<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"

       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" >

下面用spring注入以来 读取properties

<context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${jdbc.driver}"></property>
        <property name="jdbcUrl" value="${jdbc.url}"></property>
        <property name="user" value="${jdbc.username}"></property>
        <property name="password" value="${jdbc.password}"></property>
    </bean>

注解开发

Spring轻代码而重配置,注解配置提高开发效率

在这里插入图片描述

@Component("userService")
public class UserServiceImpl implements UserService {

    @Autowired
    @Qualifier("userDao")
    private UserDao userDao;

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    public void save(){
        userDao.save();
    }
}

在用注解标明并生成实例以及内部依赖后要告诉Spring去扫描注释

<context:component-scan base-package="com.Qing"></context:component-scan>

如果使用XML配置 set方法要写

注解方式 set方法可以不写

Autowired 会按照数据类型从Spring容器中进行匹配,多个对象不适用
只有单个对象时可以不用Qualifier
Qualifier按照id值从容器中进行匹配的,但是此处必须使用Autowired

Resource = Autowired+Qualifier

问题:在Spring项目中引入@Resource注解的时候,有红色下划线错误,而且输入注解的时候不能出现自动代码补全。加入javax.annotation包后,出现警告

解决办法:Spring项目中缺少javax.annotation包的依赖。在maven配置文件pom.xml中加入依赖。

    <dependency>
        <groupId>javax.annotation</groupId>
        <artifactId>jsr250-api</artifactId>
        <version>1.0</version>
    </dependency>

Spring集成JUnit

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:ApplicationContext.xml")  //使用配置文件
@ContextConfiguration(classes = {SpringConfiguration.class}) //使用注解开发

动态代理

Java中的代理可以在不改变对象类的情况下对功能进行扩张,静态代理是指程序员手写代码完成代理
而动态代理则使用JDK中的proxy类来完成,具体例子如下

interface IDog{
    void run();
}
//目标类
class GunDog implements IDog{

    @Override
    public void run() {
        System.out.println("猎狗在跑");
    }
}
class DogUtils{
    public static void method1() {
        System.out.println("增强方式一");
    }
    
    public static void method2() {
        System.out.println("增强方式二");
    }
}
class MyInvocationHandle implements InvocationHandler{
    private Object target;
    public void setTarget(Object target) {
        this.target = target;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            DogUtils.method1();
            method.invoke(target, args);
            DogUtils.method2();
            return null;
    }
}
    //生产代理对象的工厂
 class MyProxyFactory{
    public static Object getProxy(Object target) {
        MyInvocationHandle handle = new MyInvocationHandle();
        handle.setTarget(target);
        Object proxy = Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), handle);
        return proxy;
    }
 }
public class ProxyDemo {
    public static void main(String[] args) {
      IDog dog = new GunDog();
      IDog proxy =(IDog) MyProxyFactory.getProxy(dog);
      proxy.run();
    }

}

Spring中的AOP就是动态代理,并且提供了简便的语法来配置
代理可以减少代码重复性:如果A有一个方法a(), B,C,D都要使用,这个时候不用在BCD类中都创建一个A对象再操作,而使用代理,可以直接引用这个代理,并使用该功能
在这里插入图片描述

使用AOP 动态结合,把目标方法与功能增强方法分开,使用配置文件,这样一个配置可以称为一个切面
在这里插入图片描述

分为JDK代理:基于接口的动态代理
与cglib代理:基于父类的动态代理

JDK代理:

public class ProxyTest {
    public static void main(String[] args) {
        final TargetInterface target = new Target();

        //返回值就是动态生成的代理对象
        TargetInterface proxy = (TargetInterface) Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(),
                new InvocationHandler() {
                    //调用代理对象的任何方法 实质执行都是invoke方法
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        Advice.beforeSave();
                        method.invoke(target,args);
                        Advice.afterSave();
                        return null;
                    }
        });

        proxy.delete();
    }
}

由于是基于接口的,只有接口中的方法才会有增强

基于cglib

public class ProxyTest {
    public static void main(String[] args) {
        final Target target = new Target();

        //返回值 就是动态生成的代理对象 基于cglib
        //创建增强器
        Enhancer enhancer = new Enhancer();
        //设置父类
        enhancer.setSuperclass(Target.class);
        //设置回调
        enhancer.setCallback(new MethodInterceptor() {
            @Override
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {

                Advice.beforeSave();
                methodProxy.invokeSuper(o,objects); //或者是Object invoke = method.invoke(target.objects)
                Advice.afterSave();
                return null;
            }
        });
        //创建代理对象
        Target proxy = (Target)enhancer.create();

        proxy.save();
    }
}

在cglib中
对于目标类(父类)中方法增强时,可以使用两种方法,一种是
methodProxy.invokeSuper(o,objects);
或者
Object invoke = method.invoke(target.objects)
都可以达到目标

在这里插入图片描述
可以被增强的方法就叫连接点
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值