sb3

jdbc是连接数据库的东西

 

 

jdbc程序:

jdbcstudy是数据库

mybatis也能将数据存到数据库,能替代jdbc

Spring

spring是一个容器,特性是IOC(控制反转)和AOP(面向切面编程),里面可以装很多bean

IOC:想用什么功能,只用用户那边修改程序就行,不用修改业务层了,即获得依赖对象的方式反转了

spring 会自动扫描beans.xml里面所有注册的bean,其中每一个bean对应一个类,类里面的每个属性得有对应的get和set方法以实现属性的依赖注入(property里面的value),把它们new出来之后放到ApplicationContext里面,如果要用那个bean的方法,就从容器里面拿到对应的bean就ok 。之后要实现什么样的操作,在xml里面改动就OK了。

依赖注入包括构造器注入,set注入,依赖:bean的创建依赖于ioc容器,注入:bean的所有属性由容器注入

name是给bean取别名,这样在容器里可以通过别名来获取bean

 

 

 

 也可以新建applicationContext.xml里面包含多个bean,然后在通过读取applicationContext.xml来读取bean:

 

 

 

 

 xml注入例子:

 

 

 

 通过命名空间c,p简化注入方式:

 

 

 

bean scope (bean的作用域)

singleton(单例模式)(默认),每次从容器中拿bean时,都是那一个;prototype(原型模式),每次从容器中拿bean时都不一样

利用autowire可以实现自动装配,假定People类有name、Cat、Dog属性,容器会把cat和dog等bean装到bean的people里面

 

 使用@autowired将容器里面的bean自动注入带People,而且People里面不用写set方法

 

 

 

 如果有多个bean要装配,使用@Qualifier(value="aaa")可以指定装配id=aaa的那个bean

 

 

 也可以使用java的一个注解@Resource来替代@autowired和@Qualifier,它会先扫描名字,如果找不到再扫描类型

@Component:告诉spring它是个bean,扫描的话把它扫描进去,相当于<bean...>,id为类名小写

@Repository,@Service,@Controller也有同样作用,Repository用于DAO层,Service用于Service层...

@Scope指定作用域

@Value将值注入到属性中

 

 还要在xml里面告诉容器这些注解在哪个包下

 

 如果不用xml,则使用@Configuration和@Bean告诉注解在哪,@Configuration表明是配置类,此时Bean修饰的方法名为id:

 

同时还要修改Context,读取该配置类:

 

 如果A类上也加上了@Configuration,则在KuangConfig上加上@Import(A.class)能把配置类A读取进来

代理模式:

真实角色能干一些事情,代理角色代替真实角色做事情,这样客户端就只用和代理角色交互就好了。这样真实者做的事情就更加纯粹了

下例中,房东是真实者,代理者不仅可以用房东的方法,还能有自己的方法。2人都实现了接口rent(抽象角色)

 

 

 

 aop就是在原来完整的纵向开发完成后,横向加入一些功能

 

动态代理的代理类是动态生成的

反射机制应用Method:

 

首先Method获取HelloService里面的sayHello方法代表,第二个参数是sayHello方法的参数 

由于实例target有该sayHello方法,就能使用method调用实例target的sayHello方法,并传入参数

 

 动态代理步骤:

1.创建接口,定义目标类要完成的功能

 

2.创建目标类(真实对象)实现接口

 

 

 

 

 3.创建InvocationHandler接口的实现类,在invoke方法中完成代理类的功能:调用目标方法+增强功能

属性target是目标类的对象

 

 4. 使用Proxy类的静态方法,创建代理对象,并把返回值转为接口类型

proxy.sell(1)会执行handler.invoke(,sell,1)

 使用spring实现aop(本质是代理):

1.定义真实类

 

2.设置要切入的方法

 

 

 

 3.配置xml:先注册bean,然后以com...UserServiceImpl.*:com...UserServiceImpl下的所有方法作为切入点,把log切到方法前面去,afterlog切到方法后面

 

 4.从spring容器里获得已经被切入后的bean(UserService),再执行它的方法

 

 

aop实现方法2:

自定义类(切面),类里面是要切入的方法:

设置xml,自定义类作为bean,在切面里面定义切入点(要切入的位置),aop:before表示将自定义类里面的before切入到切入点(UserserviceImpl里面的所有方法)前面

 

 执行结果:

 

 注解实现aop:

定义切面,切点:

@Before:在UserServiceImpl的所有方法前加入修饰的before方法

@Around也得切入

 

配置xml:

 

 

 执行结果:

 

rabbitMq:

virtualhost:一个项目对应一个虚拟机,类似于数据库中的库,生产者和消费者都需要连接到server 上个那个虚拟机后才能操作

一个通道可以向指定的队列发送消息

 

helloworld模型:一个生产者, 一个队列,一个消费者

worker模型:一个生产者, 一个队列,多个消费者。

消费者默认自动确认的:一次性收到队列中多个消息,并当场告诉队列自己已经确认消费了,然后队列删掉这些消息,后期消费者再慢慢地一个个处理,带来的结果是平均消费

在多个消费者消费能力不同的情况下,需要消费者关掉自己的自动确认机制,在处理完消息后手动确认,同时声明一次性只拿一个消息,这样就能实现消费能力强的多消费

fanout广播订阅模型:

 

 

routing路由模型:

routingkey那个线条:error,info...

 topic模型就是多了通配符:

 application.properties配置:

# rabbitmq
spring.application.name=springboot-rabbitmq
spring.rabbitmq.host=127.0.0.1
spring.rabbitmq.port=5672
spring.rabbitmq.username=jary
spring.rabbitmq.password=qweewq
spring.rabbitmq.virtual-host=jary

 

生产者:

package com.jary.kill.hello;

import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

@Service("Sender")
public class Sender {
@Resource
private AmqpTemplate amqpTemplate;

public void sendMessage(String message){
// 交换机名,RoutingKey,消息
amqpTemplate.convertAndSend("bootDirectExchange","bootDirectRoutingKey",message);
}
}

消费者:
package com.jary.kill.hello;

import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

@Service("Customer")
public class Customer {
@Resource
private AmqpTemplate amqpTemplate;

// 配置消息监听器,spring 会自动调用,不用手动,如果该方法正常执行不报错, 就会给队列自动确认该消息
@RabbitListener(queues = {"bootDirectQueue"})
public void directReceive(String message){
System.out.println("监听器收到消息:"+message);
}
}

主类:
@SpringBootApplication
public class KillApplication {

public static void main(String[] args) {
// 启动spring ioc容器
// SpringApplication.run(KillApplication.class, args);
ApplicationContext ac = SpringApplication.run(KillApplication.class,args);
Sender sender = (Sender) ac.getBean("Sender");
sender.sendMessage("测试数据");
}
}

配置类:
package com.jary.kill.config;

import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

// 让springboot配置好
@Configuration
public class RabbitMQConfig {
// 配置一个名为bootDirectExchange的交换机
@Bean
public DirectExchange directExchange(){
return new DirectExchange("bootDirectExchange");
}

// 配置一个名为bootDirectQueue的队列
@Bean
public Queue directQueue(){
return new Queue("bootDirectQueue");
}

// 配置队列和交换机绑定,同时指定routingKey为bootDirectRoutingKey,这两个参数要和上面的方法一致就能自动注入了
@Bean
public Binding directBinding(Queue directQueue,DirectExchange directExchange){
return BindingBuilder.bind(directQueue).to(directExchange).with("bootDirectRoutingKey");
}
}


posted @ 2020-12-16 12:58  Jary霸  阅读(496)  评论(0)    收藏  举报