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");
}
}

浙公网安备 33010602011771号