简介

Apache Shiro 是 Java 的一个安全(权限)框架。主要提供了认证、授权、加密和会话管理等功能。

Authentication:身份认证/登录,验证用户是不是拥有相应的身份;
Authorization:授权,即权限验证,验证某个已认证的用户是否拥有某个权限;即判断用
户是否能进行什么操作,如:验证某个用户是否拥有某个角色。或者细粒度的验证某个用户
对某个资源是否具有某个权限;
Session Manager:会话管理,即用户登录后就是一次会话,在没有退出之前,它的所有
信息都在会话中;会话可以是普通 JavaSE 环境,也可以是 Web 环境的;
Cryptography:加密,保护数据的安全性,如密码加密存储到数据库,而不是明文存储;
Web Support:Web 支持,可以非常容易的集成到Web 环境;
Caching:缓存,比如用户登录后,其用户信息、拥有的角色/权限不必每次去查,这样可
以提高效率;
Concurrency:Shiro 支持多线程应用的并发验证,即如在一个线程中开启另一个线程,能
把权限自动传播过去;
Testing:提供测试支持;
Run As:允许一个用户假装为另一个用户(如果他们允许)的身份进行访问;
Remember Me:记住我,这个是非常常见的功能,即一次登录后,下次再来的话不用登
录了。

集成Spring

工程目录

1、引入依赖

<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.</version>
<scope>test</scope>
</dependency> <dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency> <!-- spring webmvc相关jar -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.0..RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.0..RELEASE</version>
</dependency> <!-- spring相关jar -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.0..RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.0..RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.0..RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>4.0..RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>4.0..RELEASE</version>
</dependency> <dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.</version>
</dependency> <!-- log -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.</version>
</dependency> <dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.</version>
</dependency> <!-- mysql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.</version>
</dependency> <!-- json -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.3.</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.3.</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.3.</version>
<exclusions>
<exclusion>
<artifactId>jackson-annotations</artifactId>
<groupId>com.fasterxml.jackson.core</groupId>
</exclusion>
</exclusions>
</dependency> <!-- web jstl的jar -->
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.</version>
</dependency>
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency> <!-- ehcache的jar -->
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>2.8.</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-ehcache</artifactId>
<version>1.0.</version>
</dependency> <dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.</version>
</dependency> <!--shiro -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
<version>1.3.</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-aspectj</artifactId>
<version>1.3.</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
<version>1.3.</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.3.</version>
</dependency> </dependencies>

2、Spring配置文件

applicationContext.xml

<?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:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <context:component-scan base-package="org.tarena">
<context:exclude-filter type="annotation"
expression="org.springframework.stereotype.Controller" />
</context:component-scan> <aop:aspectj-autoproxy proxy-target-class="true"/> <import resource="classpath*:/spring-*.xml" /> </beans>

spring-mvc.xml

<?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:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
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-4.0.xsd"> <!-- 开启controller注解支持 -->
<context:component-scan base-package="org.tarena.shiro"
use-default-filters="false">
<context:include-filter type="annotation"
expression="org.springframework.stereotype.Controller" />
</context:component-scan> <mvc:annotation-driven></mvc:annotation-driven>
<mvc:default-servlet-handler/> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
</beans>

spring-shiro.xml

<?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"> <!-- =========================================================
Shiro Core Components - Not Spring Specific
========================================================= -->
<!-- Shiro's main business-tier object for web-enabled applications
(use DefaultSecurityManager instead when there is no web environment)-->
<!--
. 配置 SecurityManager!
-->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="cacheManager" ref="cacheManager"/>
<!-- Single realm app. If you have multiple realms, use the 'realms' property instead. -->
<property name="sessionMode" value="native"/>
<property name="realms">
<list>
<ref bean="myRealm"/>
<ref bean="secondRealm"/>
</list>
</property> </bean> <bean id="myRealm" class="org.tarena.shiro.realm.MyRealm">
<property name="credentialsMatcher" >
<bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
<property name="hashAlgorithmName" value="MD5"></property>
<property name="hashIterations" value=""></property>
</bean>
</property>
</bean> <bean id="secondRealm" class="org.tarena.shiro.realm.SecondRealm">
<property name="credentialsMatcher" >
<bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
<property name="hashAlgorithmName" value="SHA1"></property>
<property name="hashIterations" value=""></property>
</bean>
</property>
</bean> <!-- Let's use some enterprise caching support for better performance. You can replace this with any enterprise
caching framework implementation that you like (Terracotta+Ehcache, Coherence, GigaSpaces, etc -->
<!--
. 配置 CacheManager.
2.1 需要加入 ehcache 的 jar 包及配置文件.
-->
<bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
<!-- Set a net.sf.ehcache.CacheManager instance here if you already have one. If not, a new one
will be creaed with a default config:
<property name="cacheManager" ref="ehCacheManager"/> -->
<!-- If you don't have a pre-built net.sf.ehcache.CacheManager instance to inject, but you want
a specific Ehcache configuration to be used, specify that here. If you don't, a default
will be used.: -->
<property name="cacheManagerConfigFile" value="classpath:ehcache.xml"/>
</bean> <!-- =========================================================
Shiro Spring-specific integration
========================================================= -->
<!-- Post processor that automatically invokes init() and destroy() methods
for Spring-configured Shiro objects so you don't have to
) specify an init-method and destroy-method attributes for every bean
definition and
) even know which Shiro objects require these methods to be
called. -->
<!--
. 配置 LifecycleBeanPostProcessor. 可以自定的来调用配置在 Spring IOC 容器中 shiro bean 的生命周期方法.
-->
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/> <!-- Enable Shiro Annotations for Spring-configured beans. Only run after
the lifecycleBeanProcessor has run: -->
<!--
. 启用 IOC 容器中使用 shiro 的注解. 但必须在配置了 LifecycleBeanPostProcessor 之后才可以使用.
-->
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
depends-on="lifecycleBeanPostProcessor"/>
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
<property name="securityManager" ref="securityManager"/>
</bean> <!-- Define the Shiro Filter here (as a FactoryBean) instead of directly in web.xml -
web.xml uses the DelegatingFilterProxy to access this bean. This allows us
to wire things with more control as well utilize nice Spring things such as
PropertiesPlaceholderConfigurer and abstract beans or anything else we might need: -->
<!--
. 配置 ShiroFilter.
6.1 id 必须和 web.xml 文件中配置的 DelegatingFilterProxy 的 <filter-name> 一致.
若不一致, 则会抛出: NoSuchBeanDefinitionException. 因为 Shiro 会来 IOC 容器中查找和 <filter-name> 名字对应的 filter bean.
-->
<!-- Define the Shiro Filter here (as a FactoryBean) instead of directly in web.xml -
web.xml uses the DelegatingFilterProxy to access this bean. This allows us
to wire things with more control as well utilize nice Spring things such as
PropertiesPlaceholderConfigurer and abstract beans or anything else we might need: -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager"/>
<property name="loginUrl" value="/login"/>
<property name="successUrl" value="/list"/>
<property name="unauthorizedUrl" value="/unauthorized"/>
<!-- <property name="filterChainDefinitionMap" ref="filterChainDefinitionMap"></property>-->
<!-- The 'filters' property is not necessary since any declared javax.servlet.Filter bean
defined will be automatically acquired and available via its beanName in chain
definitions, but you can perform overrides or parent/child consolidated configuration
here if you like: -->
<!-- <property name="filters">
<util:map>
<entry key="aName" value-ref="someFilterPojo"/>
</util:map>
</property> -->
<property name="filterChainDefinitions">
<value>
/**/login = anon
/toLogin = anon
# everything else requires authentication:
/** = authc
</value>
</property>
</bean> <!--
<bean id="filterChainDefinitionMapFactory" class="org.tarena.shiro.factory.FilterChainDefinitionMapFactory">
</bean> <bean id="filterChainDefinitionMap" factory-bean="filterChainDefinitionMapFactory" factory-method="bulidFilterChainDefinitionMap"></bean>
-->
</beans>

ehcache.xml

<!--
~ Licensed to the Apache Software Foundation (ASF) under one
~ or more contributor license agreements. See the NOTICE file
~ distributed with this work for additional information
~ regarding copyright ownership. The ASF licenses this file
~ to you under the Apache License, Version 2.0 (the
~ "License"); you may not use this file except in compliance
~ with the License. You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing,
~ software distributed under the License is distributed on an
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
~ KIND, either express or implied. See the License for the
~ specific language governing permissions and limitations
~ under the License.
--> <!-- EhCache XML configuration file used for Shiro spring sample application -->
<ehcache> <!-- Sets the path to the directory where cache .data files are created. If the path is a Java System Property it is replaced by
its value in the running VM. The following properties are translated:
user.home - User's home directory
user.dir - User's current working directory
java.io.tmpdir - Default temp file path -->
<diskStore path="java.io.tmpdir/shiro-spring-sample"/> <!--Default Cache configuration. These will applied to caches programmatically created through
the CacheManager. The following attributes are required: maxElementsInMemory - Sets the maximum number of objects that will be created in memory
eternal - Sets whether elements are eternal. If eternal, timeouts are ignored and the
element is never expired.
overflowToDisk - Sets whether elements can overflow to disk when the in-memory cache
has reached the maxInMemory limit. The following attributes are optional:
timeToIdleSeconds - Sets the time to idle for an element before it expires.
i.e. The maximum amount of time between accesses before an element expires
Is only used if the element is not eternal.
Optional attribute. A value of means that an Element can idle for infinity.
The default value is .
timeToLiveSeconds - Sets the time to live for an element before it expires.
i.e. The maximum time between creation time and when an element expires.
Is only used if the element is not eternal.
Optional attribute. A value of means that and Element can live for infinity.
The default value is .
diskPersistent - Whether the disk store persists between restarts of the Virtual Machine.
The default value is false.
diskExpiryThreadIntervalSeconds- The number of seconds between runs of the disk expiry thread. The default value
is seconds.
memoryStoreEvictionPolicy - Policy would be enforced upon reaching the maxElementsInMemory limit. Default
policy is Least Recently Used (specified as LRU). Other policies available -
First In First Out (specified as FIFO) and Less Frequently Used
(specified as LFU)
--> <defaultCache
maxElementsInMemory=""
eternal="false"
timeToIdleSeconds=""
timeToLiveSeconds=""
overflowToDisk="false"
diskPersistent="false"
diskExpiryThreadIntervalSeconds=""
/> <!-- We want eternal="true" (with no timeToIdle or timeToLive settings) because Shiro manages session
expirations explicitly. If we set it to false and then set corresponding timeToIdle and timeToLive properties,
ehcache would evict sessions without Shiro's knowledge, which would cause many problems
(e.g. "My Shiro session timeout is 30 minutes - why isn't a session available after 2 minutes?"
Answer - ehcache expired it due to the timeToIdle property set to seconds.) diskPersistent=true since we want an enterprise session management feature - ability to use sessions after
even after a JVM restart. -->
<cache name="shiro-activeSessionCache"
maxElementsInMemory=""
eternal="true"
overflowToDisk="true"
diskPersistent="true"
diskExpiryThreadIntervalSeconds=""/> <cache name="org.apache.shiro.realm.SimpleAccountRealm.authorization"
maxElementsInMemory=""
eternal="false"
timeToLiveSeconds=""
overflowToDisk="false"/> </ehcache>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5"> <!-- needed for ContextLoaderListener -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param> <!-- Bootstraps the root web application context before servlet initialization -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener> <!-- 设置servlet编码开始 -->
<filter>
<filter-name>Set Character Encoding</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>Set Character Encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping> <!-- The front controller of this Spring Web application, responsible for handling all application requests -->
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet> <!-- Map all requests to the DispatcherServlet for handling -->
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping> <!-- Shiro Filter is defined in the spring application context: -->
<!--
1. 配置 Shiro 的 shiroFilter.
2. DelegatingFilterProxy 实际上是 Filter 的一个代理对象. 默认情况下, Spring 会到 IOC 容器中查找和
<filter-name> 对应的 filter bean. 也可以通过 targetBeanName 的初始化参数来配置 filter bean 的 id.
-->
<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<param-name>targetFilterLifecycle</param-name>
<param-value>true</param-value>
</init-param>
</filter> <filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping> </web-app>

shiro与spring集成的更多相关文章

  1. Shiro - 与Spring集成

    本文是针对web应用web.xml: <filter> <filter-name>shiroFilter</filter-name> <filter-clas ...

  2. [原]CAS和Shiro在spring中集成

    shiro是权限管理框架,现在已经会利用它如何控制权限.为了能够为多个系统提供统一认证入口,又研究了单点登录框架cas.因为二者都会涉及到对session的管理,所以需要进行集成. Shiro在1.2 ...

  3. Shiro之身份认证、与spring集成(入门级)

    目录 1. Shro的概念 2. Shiro的简单身份认证实现 3. Shiro与spring对身份认证的实现 前言: Shiro 可以非常容易的开发出足够好的应用,其不仅可以用在 JavaSE 环境 ...

  4. Spring集成shiro做登陆认证

    一.背景 其实很早的时候,就在项目中有使用到shiro做登陆认证,直到今天才又想起来这茬,自己抽空搭了一个spring+springmvc+mybatis和shiro进行集成的种子项目,当然里面还有很 ...

  5. spring集成shiro报错解决(no bean named 'shiroFilter' is defined)

    引言: 本人在使用spring集成shiro是总是报“no bean named 'shiroFilter' is defined”,网上的所有方式挨个试了一遍,又检查了一遍, 还是没有解决,最后,抱 ...

  6. shiro实战系列(十五)之Spring集成Shiro

    Shiro 的 JavaBean 兼容性使得它非常适合通过 Spring XML 或其他基于 Spring 的配置机制.Shiro 应用程序需要一个具 有单例 SecurityManager 实例的应 ...

  7. Java 权限框架 Shiro 实战二:与spring集成、filter机制

    转自:https://www.cnblogs.com/digdeep/archive/2015/07/04/4620471.html Shiro和Spring的集成,涉及到很多相关的配置,涉及到shi ...

  8. 2017.2.13 开涛shiro教程-第十二章-与Spring集成(二)shiro权限注解

    原博客地址:http://jinnianshilongnian.iteye.com/blog/2018398 根据下载的pdf学习. 第十二章-与Spring集成(二)shiro权限注解 shiro注 ...

  9. 2017.2.13 开涛shiro教程-第十二章-与Spring集成(一)配置文件详解

    原博客地址:http://jinnianshilongnian.iteye.com/blog/2018398 根据下载的pdf学习. 第十二章-与Spring集成(一)配置文件详解 1.pom.xml ...

随机推荐

  1. Visual Studio 2019 使用 Web Deploy 发布远程站点到IIS服务器

    Visual Studio 2019 使用 Web Deploy 发布远程站点到IIS服务器的方式 在开发完项目之后,我们需要把开发的项目发布到指定的服务器上,有两种方式,如下 1.把项目发布成文件系 ...

  2. git只提交修改部分的代码

    思路: 先用git status 查找出哪些文件被修改过了,然后 只git commit odin/code/pom.xml 1. $ git status (查看当前更改的代码) On branch ...

  3. 蓝牙BLE: GATT Profile 简介(GATT 与 GAP)

    一. 引言 现在低功耗蓝牙(BLE)连接都是建立在 GATT (Generic Attribute Profile) 协议之上.GATT 是一个在蓝牙连接之上的发送和接收很短的数据段的通用规范,这些很 ...

  4. NAXSI means Nginx Anti XSS & SQL Injection. NAXSI is an open-source, high performance, low rules maintenance WAF for NGINX

    nbs-system/naxsi: NAXSI is an open-source, high performance, low rules maintenance WAF for NGINXhttp ...

  5. 字典树(查找树) leetcode 208. Implement Trie (Prefix Tree) 、211. Add and Search Word - Data structure design

    字典树(查找树) 26个分支作用:检测字符串是否在这个字典里面插入.查找 字典树与哈希表的对比:时间复杂度:以字符来看:O(N).O(N) 以字符串来看:O(1).O(1)空间复杂度:字典树远远小于哈 ...

  6. pytorch设置多GPU运行的方法

    1.DataParallel layers (multi-GPU, distributed) 1)DataParallel CLASS torch.nn.DataParallel(module, de ...

  7. android 应用签名的作用

    来源:https://www.jianshu.com/p/61206c96471a 1..应用程序升级:如果你希望用户无缝升级到新的版本,那么你必须用同一个证书进行签名.这是由于只有以同一个证书签名, ...

  8. realsense SDK编译 debug

    1>------ 已启动全部重新生成: 项目: ZERO_CHECK, 配置: Debug x64 ------1> Checking Build System1> CMake do ...

  9. Spring cloud微服务安全实战-6-7jwt改造总结

    限流的改造. 同样注意,不要声明成Spring的Bean 在上面声明Rateliiter 如果能获取到权限继续往下走,没权限就返回,to many request的错误信息. 加到过滤器链上 加载Sp ...

  10. mysql存储过程中declare 和set 定义变量的区别

    declare为对变量进行声明,声明必须制定变量的数据类型,只能写在过程的前面set是对变量赋值,可以放在过程的任何地方对没有declare声明过的变量赋值,该变量必须以加上@号,否则会报错 DECL ...